leetcode349. 两个数组的交集

原理

代码通过哈希数组统计元素出现的次数,找出两个数组中共同存在的元素。核心思路是:

  1. 哈希数组映射:用两个数组 hash1 和 hash2 分别记录 nums1 和 nums2 中每个元素的出现次数。
  2. 交集判断:遍历哈希数组,若某个元素在两个哈希数组中的计数均不为零,说明它是交集元素。

步骤

  1. 初始化哈希数组

    • 创建两个长度为 1001 的数组 hash1 和 hash2,初始值全为 0
    • 因为题目中元素范围为 [0, 1000],哈希数组的索引直接对应元素值,值对应出现次数。
  2. 统计元素出现次数

    • 遍历 nums1,将每个元素的值作为索引,在 hash1 中对应的位置计数 +1
    • 同样遍历 nums2,更新 hash2
  3. 找出交集元素

    • 遍历哈希数组 hash1(或 hash2,因为长度相同),检查每个索引 i
    • 如果 hash1[i] 和 hash2[i] 均不为零,说明 i 是两个数组的交集元素,将其加入结果。

图示

假设输入为 nums1 = [1, 2, 2, 1]nums2 = [2, 2]

  1. 统计哈希数组

    • hash1[1] = 2hash1[2] = 2,其余为 0
    • hash2[2] = 2,其余为 0
  2. 遍历哈希数组

    • 检查索引 0 到 1000,发现只有索引 2 满足 hash1[2] != 0 且 hash2[2] != 0
    • 将 2 加入结果。

最终结果:[2]


代码关键行注释

vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    vector<int> ans;
    vector<int> hash1(1001, 0);  // 哈希数组1,记录nums1中元素的出现次数
    vector<int> hash2(1001, 0);  // 哈希数组2,记录nums2中元素的出现次数

    // 遍历nums1,统计元素出现次数
    for (int i = 0; i < nums1.size(); i++) {
        hash1[nums1[i]]++;  // nums1的元素值作为索引,计数+1
    }

    // 遍历nums2,统计元素出现次数
    for (int i = 0; i < nums2.size(); i++) {
        hash2[nums2[i]]++;  // nums2的元素值作为索引,计数+1
    }

    // 遍历哈希数组,找出交集元素
    for (int i = 0; i < hash1.size(); i++) {  // 哈希数组长度为1001
        if (hash1[i] != 0 && hash2[i] != 0) {  // 两个数组均包含该元素
            ans.push_back(i);  // 将元素值i加入结果
        }
    }
    return ans;
}

完整代码

#include <iostream>
#include <istream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;

vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    vector<int> ans;
    vector<int> hash1(1001, 0);
    vector<int> hash2(1001, 0);
    for (int i = 0; i < nums1.size(); i++) {
        hash1[nums1[i]]++;
    }
    for (int i = 0; i < nums2.size(); i++) {
        hash2[nums2[i]]++;
    }
    for (int i = 0; i < hash1.size(); i++) {
        if (hash1[i] != 0 && hash2[i] != 0) {
            ans.push_back(i);
        }
    }
    return ans;
}

int main() {
    vector<int> nums1;
    string line1;
    getline(cin, line1);
    istringstream iss1(line1);
    int num1;
    while (iss1 >> num1) {
        nums1.push_back(num1);
    }
    vector<int> nums2;
    string line2;
    getline(cin, line2);
    istringstream iss2(line2);
    int num2;
    while (iss2 >> num2) {
        nums2.push_back(num2);
    }
    vector<int> ans = intersection(nums1, nums2);
    for (int i = 0; i < ans.size(); i++) {
        cout << ans[i] << " ";
    }
    return 0;
}

时间复杂度

  1. 统计哈希数组
    • 遍历 nums1 和 nums2,时间复杂度为 ​O(n + m),其中 n 和 m 是数组长度。
  2. 遍历哈希数组
    • 哈希数组长度为 1001,时间复杂度为 ​O(1001)
  3. 总时间复杂度:​O(n + m + 1001),即线性复杂度。

总结

  1. 优点

    • 代码简洁高效,适用于元素范围明确且较小的情况(如 [0, 1000])。
    • 哈希数组直接通过索引访问,查询时间为 O(1)
  2. 局限性

    • 元素范围必须已知且较小,无法处理负数或超过 1000 的值。
    • 哈希数组固定长度为 1001,可能浪费内存(例如数组中只有少数元素时)。
  3. 适用场景

    • 明确元素范围(如题目中给定数值范围)时,此方法是理想选择。
    • 需要快速实现且不追求通用性时,可直接使用此代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值