三个有序数组的交集

Submission

运行时间: 26 ms

内存: 16.4 MB

class Solution:
    def arraysIntersection(self, arr1: List[int], arr2: List[int], arr3: List[int]) -> List[int]:

        res = []
        p1 = 0
        p2 = 0
        p3 = 0
        n1 = len(arr1)
        n2 = len(arr2)
        n3 = len(arr3)
        while p1 < n1 and p2 < n2 and p3 < n3:
            if arr1[p1] == arr2[p2] and arr2[p2] == arr3[p3]:
                res.append(arr1[p1])
                p1 += 1
                p2 += 1
                p3 += 1
            else:
                if arr1[p1] < arr2[p2]:
                    p1 += 1
                elif arr2[p2] < arr3[p3]:
                    p2 += 1
                else:
                    p3 += 1
        return res

Explain

该题解采用了三指针的方法来寻找三个有序数组的交集。每个数组都有一个指针(p1, p2, p3),开始时都指向各自数组的第一个元素。循环进行比较,如果三个指针指向的元素都相同,则该元素为交集的一部分,将其加入结果列表,并将三个指针都前移一位。如果不匹配,则移动指向最小元素的指针,以期在较大元素的数组中寻找匹配。这个过程一直进行,直到任何一个指针超出其对应数组的长度。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def arraysIntersection(self, arr1: List[int], arr2: List[int], arr3: List[int]) -> List[int]:
        # 结果列表
        res = []
        # 初始化三个数组的指针
        p1, p2, p3 = 0, 0, 0
        # 获取三个数组的长度
        n1, n2, n3 = len(arr1), len(arr2), len(arr3)
        # 当三个指针都没有越界时循环
        while p1 < n1 and p2 < n2 and p3 < n3:
            # 如果三个指针指向的元素相等
            if arr1[p1] == arr2[p2] and arr2[p2] == arr3[p3]:
                res.append(arr1[p1])  # 加入到结果列表
                p1 += 1  # 三个指针同时前进
                p2 += 1
                p3 += 1
            else:
                # 移动指向最小元素的指针
                if arr1[p1] < arr2[p2]:
                    p1 += 1
                elif arr2[p2] < arr3[p3]:
                    p2 += 1
                else:
                    p3 += 1
        return res  # 返回结果列表

Explore

在这种算法中,目标是找到所有三个数组共同的元素。当三个指针所指的元素不相同时,意味着最小的那个元素不可能是共同元素,因为它比其他至少一个数组中的元素小。如果我们移动指向最小元素的指针,我们可以将这个指针的元素逐渐增大,试图找到一个匹配较大元素的值,从而寻找交集。反之,如果移动较大元素的指针,它们的值将会越来越大,而最小的那个元素还是不会匹配,这样做无法帮助我们找到共同元素,反而可能错过潜在的交集。

算法通过仅在找到共同元素时同时移动所有三个指针来保证。如果没有找到共同元素,算法只会移动指向最小元素的那个指针,这样做是为了逐步逼近其他两个较大元素的值。通过这种方式,只要有可能形成交集的元素,这种方法最终会考虑到它们,因为其他两个指针会保持不动,直到最小的指针指向的元素增加到足够大的值去匹配它们为止。这样可以确保每个数组中的每个元素都会被考虑到,而不会遗漏任何可能的交集。

是的,这种三指针方法同样适用于处理包含重复元素的数组。由于数组是有序的,相同的元素会连续出现。算法在发现一组相等的元素时,会将它们加入到结果中,并同时移动所有三个指针。这意味着即使有重复元素,每个数组的指针都会在找到共同元素后移动到下一个位置,继续寻找下一个可能的交集。因此,即使数组中有重复元素,该算法也能正确地找到所有交集元素。