两个数组的交集

标签: 数组 哈希表 双指针 二分查找 排序

难度: Easy

给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

Submission

运行时间: 21 ms

内存: 16.2 MB

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        set1 = set()
        myDict = collections.defaultdict(int)
        for i in nums1:
            myDict[i] = 1
        for i in nums2:
            if myDict[i] != 0:
                set1.add(i)
        return list(set1)

Explain

该题解的思路是先用一个字典myDict记录nums1中每个元素出现的次数(都记为1),然后遍历nums2,如果nums2中的元素在myDict中出现过(即值不为0),就将该元素添加到一个set集合set1中。最后将set1转换为列表返回。通过使用set自动去重的特性,可以确保返回的交集元素都是唯一的。

时间复杂度: O(m+n)

空间复杂度: O(m)

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        set1 = set()
        myDict = collections.defaultdict(int)
        # 记录nums1中每个元素出现的次数
        for i in nums1:
            myDict[i] = 1
        # 遍历nums2,将nums2中在nums1中出现过的元素添加到set1中
        for i in nums2:
            if myDict[i] != 0:
                set1.add(i)
        # 将set1转换为列表返回
        return list(set1)

Explore

在这个题解中,目的是找出两个数组的交集,即只需要确定nums2中的元素是否在nums1中出现过,不关心出现的次数。将nums1中的每个元素的次数设为1是为了简化处理过程,因为只需标记这个元素是否存在。如果记录实际出现次数,将增加不必要的复杂度,而且对最终结果没有影响,因为题目只要求返回交集中不重复的元素。

使用set集合存储交集元素的主要好处是set自带去重功能,可以自动处理重复元素。这样,当nums2中的元素在nums1中存在时,即使这个元素在nums2中出现多次,添加到set中也只会保留一个。这直接满足了题目要求输出结果中每个元素唯一的需求,简化了代码的复杂度。

在这种情况下,检查`myDict[i] != 0`是足够的,因为字典中的值被初始化为1,表示nums1中存在该元素,且仅用于标记存在性而非计数。没有必要采用更严格的条件,因为额外的条件不会提供更多有用的信息。如果nums1中的元素不在nums2中,则这个元素对应的字典值(默认为0)不满足条件,因此不会被添加到结果集中。

如果nums1或nums2为空数组,这个解法仍然可以正确处理。这是因为如果nums1为空,字典myDict将不会有任何键值对,所以在遍历nums2时,所有元素的检查条件`myDict[i] != 0`都将不满足,结果集set1保持为空。同理,如果nums2为空,循环体内的代码不会执行,set1也将保持为空。无论哪种情况,最终返回的是空列表,正确反映了交集的状态。