这场比赛用C++写了两个题,在赛后用python补题收获很多,学习了一些python的内置函数。方法学习源于其他优秀的博主。
6120. 数组能形成多少数对(A题)
思路
方法一:我自己写的算法,先对nums排序,之后遍历数组找相邻的位置是否相同。 方法二:统计每个数出现的次数nums,然后将nums除以2再累加得到,就是求的第一个答案,未匹配的用nums的长度减去匹配对数的两倍即可。
代码
class Solution:
def numberOfPairs(self, nums: List[int]) -> List[int]:
cnt = Counter(nums)
pairs = sum(num // 2 for num in cnt.values())
return [pairs, len(nums) - pairs * 2]
6164. 数位和相等数对的最大和(B题)
思路
1.按数位分组,键存数位和,值存本身 2.用大根堆来维护前两大的数
代码
class Solution:
def maximumSum(self, nums: List[int]) -> int:
groups = defaultdict(list)
for num in nums:
s = 0
n = num
while n:
s += n % 10
n //= 10
if len(groups[s]) < 2 :
heappush(groups[s], num)
else:
heappushpop(groups[s], num)
ans = -1
for g in groups.values():
if len(g) > 1:
ans = max(ans, g[-1] + g[-2])
return ans
6121. 裁剪数字后查询第 K 小的数字(C题)
思路
利用基数排序的原理进行排序。 首先我们要用到zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。 然后用zip函数将nums和queries数组的下标存起来,进行排序,这里一定要用sorted稳定的排序。 然后用基数排序的思想先对queries的trim进行排序,nums从最后一列开始进行排序,然后找到对应的trim,再取第k小的数的下表。 最后将这些下标存到ans数组中返回。
代码
class Solution:
def smallestTrimmedNumbers(self, nums: List[str], queries: List[List[int]]) -> List[int]:
qs = sorted(zip(queries, range(len(queries))), key=lambda q: q[0][1])
a = sorted(zip(nums, range(len(nums))), key=lambda t: t[0][-1])
j = 2
ans = [0] * len(queries)
for (k, trim),i in qs:
while j <= trim:
a.sort(key=lambda t:t[0][-j])
j += 1
ans[i] = a[k - 1][1]
return ans
6122. 使数组可以被整除的最少删除次数(D题)
思路
先求numsDivide的最大公约数g,然后在nums中找到最小的能被g整除的数,记录下来,删除的个数就是nums中比g小的数。 这里要用到reduce函数,reduce函数,将第一个集合中的前两个运算,然后再将运算结果与第三个进行运算。
代码
class Solution:
def minOperations(self, nums: List[int], numsDivide: List[int]) -> int:
g = reduce(gcd, numsDivide)
mn = min((num for num in nums if g % num == 0), default = 0)
if mn == 0:
return -1
return sum(num < mn for num in nums)
|