📜  给定数组中唯一比率分数对的最大计数(1)

📅  最后修改于: 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)$,可以过掉这个题目。