📜  从两个数组中计算对,其模运算产生 K(1)

📅  最后修改于: 2023-12-03 14:49:21.129000             🧑  作者: Mango

从两个数组中计算对,其模运算产生 K

经典面试题目:给定两个整数数组 A 和 B ,需要从两个数组中各取出一个数,使得它们之和模 K 值相等,统计有几对满足条件。

解法一:暴力枚举

这是最显然的方法,两层循环暴力枚举数组 A 和 B 中的每一个数,判断它们之和是否满足条件。时间复杂度 O(N^2)

class Solution:
    def congruentPairs(self, nums1: List[int], nums2: List[int], k: int) -> int:
        count = 0

        for a in nums1:
            for b in nums2:
                if (a + b) % k == 0:
                    count += 1

        return count
解法二:哈希表

由于我们只关心每个数模 K 的余数,因此可以使用哈希表来记录余数出现的次数,然后枚举 A 数组中的数,用 K 减去它的余数得到目标余数,再查找 B 数组中是否存在这样的余数。

class Solution:
    def congruentPairs(self, nums1: List[int], nums2: List[int], k: int) -> int:
        count = 0
        freq = {}

        for b in nums2:
            if b % k not in freq:
                freq[b % k] = 0
            freq[b % k] += 1

        for a in nums1:
            target = (k - a % k) % k
            if target in freq:
                count += freq[target]

        return count

时间复杂度 O(N),空间复杂度 O(N)

解法三:排序+双指针

将数组 A 和 B 排序,然后用两个指针分别指向 A 和 B 的开头,向后扫描,如果当前两个数之和模 K 值小于目标余数,则右移 A 的指针,如果大于目标余数,则左移 B 的指针,否则加入统计结果中。

class Solution:
    def congruentPairs(self, nums1: List[int], nums2: List[int], k: int) -> int:
        count = 0
        nums1.sort()
        nums2.sort()

        i, j = 0, len(nums2) - 1
        while i < len(nums1) and j >= 0:
            s = nums1[i] + nums2[j]
            if s % k == 0:
                c1, c2 = 1, 1
                while i + 1 < len(nums1) and nums1[i+1] == nums1[i]:
                    c1 += 1
                    i += 1
                while j - 1 >= 0 and nums2[j-1] == nums2[j]:
                    c2 += 1
                    j -= 1
                count += c1 * c2
                i += 1
                j -= 1
            elif s % k > k // 2:
                j -= 1
            else:
                i += 1

        return count

时间复杂度 O(N log N),空间复杂度 O(1)