350. Intersection of Two Arrays II*

本文详细介绍了LeetCode上编号为350的问题“两数组交集 II”的解决方法,提供了四种不同的C++实现方案,包括使用哈希表和排序的方法,对每种方法进行了代码解析,帮助读者理解并掌握此题的多种解题思路。

350. Intersection of Two Arrays II*

https://leetcode.com/problems/intersection-of-two-arrays-ii/

题目描述

Given two arrays, write a function to compute their intersection.

Example 1:

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]

Example 2:

Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [4,9]

Note:

  • Each element in the result should appear as many times as it shows in both arrays.

  • The result can be in any order.
    Follow up:

  • What if the given array is already sorted? How would you optimize your algorithm?

  • What if nums1's size is small compared to nums2's size? Which algorithm is better?

  • What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?

C++ 实现 1

20210322 更新: 代码详解见 C++ 实现 2. 这次更新主要是哈希表记录元素较少的数组中的元素. 另外 C++ 实现 3 提供了利用排序来做的实现.

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        if (nums1.size() > nums2.size()) std::swap(nums1, nums2);
        unordered_map<int, int> record;
        for (auto &a : nums1) record[a] ++;
        vector<int> res;
        for (auto &a : nums2) {
            if (record.count(a)) {
                res.push_back(a);
                record[a] --;
                if (record[a] == 0) record.erase(a);
            }
        }
        return res;
    }
};

C++ 实现 2

用一个哈希表. 先统计 nums1 中的元素以及个数, 保存到 freq 中, 然后遍历 nums2, 判断每个元素是否在 freq 中, 同时还要保证对应的个数不为 0, 因为每次从 nums2 中找到了交集中的元素, freq 对应的个数需要减 1.

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int, int> freq;
        for (const auto &d : nums1)
            freq[d] ++;

        vector<int> res;
        for (const auto &d : nums2) {
            if (freq.find(d) != freq.end() && freq[d] != 0) {
                res.push_back(d);
                freq[d] --;
            }
        }
        return res;
    }
};

C++ 实现 3

使用排序来实现. 对两个数组从小到大排好序后, 然后使用 ij 分别来遍历两个数组. 如果两个元素相等, 那么就将该元素加入 res 中; 如果不相等, 那么只需要移动指向更小元素的索引即可.

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        std::sort(nums1.begin(), nums1.end());
        std::sort(nums2.begin(), nums2.end());
        int i = 0, j = 0;
        vector<int> res;
        while (i < nums1.size() && j < nums2.size()) {
            if (nums1[i] == nums2[j]) {
                res.push_back(nums1[i]);
                ++ i, ++ j;
            } else if (nums1[i] < nums2[j]) ++ i;
            else ++ j;
        }
        return res;
    }
};

C++ 实现 4

用两个哈希表的做法.

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        unordered_map<int, int> set1, set2;
        for (auto &n : nums1) set1[n] ++;
        for (auto &n : nums2) set2[n] ++;
        for (auto &p : set1) {
            if (set2.count(p.first)) {
                int n = std::min(set2[p.first], p.second);
                auto tmp = vector<int>(n, p.first);
                std::copy(tmp.begin(), tmp.end(), back_inserter(res));
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值