这场比赛用C++写了两个题,在赛后用python补题收获很多,学习了一些python的内置函数。方法学习源于其他优秀的博主。
方法一:我自己写的算法,先对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]
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
利用基数排序的原理进行排序。
首先我们要用到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 # j记录当前排到字符串第几列
ans = [0] * len(queries) # 定义一个答案数组
for (k, trim),i in qs:
while j <= trim: # 排到第trim个
a.sort(key=lambda t:t[0][-j]) # 对倒数第j列进行排序
j += 1 # 再下一趟
ans[i] = a[k - 1][1] # 记录排序后的第k小的下标
return ans
先求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)