两个数组的交集 349

54 阅读3分钟

力扣 349 两个数组的交集

给定两个数组 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

一. 哈希 unordered_set

首先拆解题目要求

  1. 重复数字只保留一份
  2. 输出不要求有序
  3. 只需要存单个数值

分析各哈希容器的特点

容器底层结构存储形式增删查平均时间复杂度是否有序
unordered_set哈希表单值O(1)无序
set红黑树单值O(log n)自动升序
unordered_map哈希表key-value 键值对O(1)无序
map红黑树key-value 键值对O(log n)自动升序

根据题目要求 单值无序 可快速判断出使用 unordered_set 为四种容器里面最优解。

✅利用 unordered_set 符合力扣格式的代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set;
        unordered_set<int> nums_set(nums1.begin(), nums1.end());
        for (int num : nums2) {
            if (nums_set.find(num) != nums_set.end()) {
                result_set.insert(num);
            }
        }
       
        return vector<int>(result_set.begin(), result_set.end());
    }
};

核心思路

  1. nums_set(nums1.begin(), nums1.end()),将 nums1 全部放入unordered_set,自动剔除 nums1 内部重复元素
  2. for (int num : nums2),for 循环 依次取出 nums2 中每一个元素,赋值给临时变量 num
  3. if (nums_set.find(num) != nums_set.end()) 判断当前 num 是否同时存在于 num1 数组,核心原理是 nums_set.find(num) 表示在集合里搜寻 num ,找到则返回指向该元素的迭代器;找不到则返回nums_set.end(),因此 != end() 等价于找到了
  4. result_set.insert(num) 表示将符合 if 条件的元素插入结果集合中,如果已经存在也不会报错,因为 unordered_set 会自动去重
  5. return vector<int>(result_set.begin(), result_set.end()) 把存好交集元素的集合,转换成数组格式返回给判题系统

简单思路如下图所示: 两个数组的交集  349_20260725_151930.png

  • 时间复杂度: O(n + m) m 是最后要把 set转成vector
  • 空间复杂度: O(n)

二. 哈希 数组

当题目确定了 数据范围 时就可以考虑使用数组来解答,例如本题给出:

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

因此可以根据范围设定一个哈希数组,大小可定为 1005

✅利用数组符合力扣格式的代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int>result_set;
        int hash[1005] = {0};
        for(int num : nums1){
            hash[num] = 1;
        }
        for(int num : nums2){
            if(hash[num] == 1){
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

核心思路nums1 每出现一个元素,哈希数组对应索引处值便赋为一,然后遍历 nums2,如果其中某值对应索引值处值为一,说明该值在 nums1nums2 中均出现过,则将其插入到 result_set 中,最后将形式转换成符合条件的形式。

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