📅  最后修改于: 2023-12-03 15:41:16.949000             🧑  作者: Mango
给定一个整数数组nums
,计算其中的唯一比率分数对的最大数量。比率分数对是指两个数的比率(分数)相同。要求计算唯一的分数对。
首先我们需要明确,如果两个数的比率相等,它们的最大公约数一定相等。因此我们可以用一个字典gcd_dict
记录每个比率(对应最大公约数)出现的次数,然后对每个比率出现的次数进行两两组合计算出分数对的总数。需要注意的是不能选择同一个数(即分子、分母相同),需要将这种情况单独计算。
算法的时间复杂度是$O(n^2)$,可以通过本题。当然还有更优秀的算法,比如用哈希表记录出现的分数,类似于TwoSum这一类问题,可以将时间复杂度降到$O(n)$。
def max_points(nums: List[int]) -> int:
n = len(nums)
if n <= 1:
return n
def gcd(a, b):
while b:
a, b = b, a % b
return a
res = 0
for i in range(n):
if res >= n - i or res > n // 2: # 优化1:如果剩余的数少于当前最大值或者分数对数量已经超过了一半,直接返回。
break
gcd_dict = {} # 每次循环初始化字典
overlap = 0 # 记录分子、分母相同时的次数
for j in range(i + 1, n):
dx, dy = nums[i] - nums[j], nums[j] # 转换成dx,dy,避免除数为0的问题
if dx == 0 and dy == 0: # 如果分子、分母相等
overlap += 1
continue
g = gcd(dx, dy)
dx //= g
dy //= g
if (dx, dy) in gcd_dict:
gcd_dict[(dx, dy)] += 1
else:
gcd_dict[(dx, dy)] = 1
res = max(res, max(gcd_dict.values() or [0]) + overlap + 1) # 优化2:如果字典为空,说明没有分数对,直接返回0
return res
本题的关键在于将分数转换成最简形式,这样可以避免出现意想不到的结果(例如$\frac{2}{4}$和$\frac{1}{2}$就是相同的)。时间复杂度为$O(n^2)$,可以过掉这个题目。