Intersection of Two Arrays II

博客围绕计算两个数组交集展开。先给出题目要求,包括示例及后续拓展问题。接着阐述思路,普通情况用unordered_map记录数字及次数;数组有序用双指针法;内存有限时,根据不同情况采用构建hashMap或外部排序等方法。最后提及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,题目要求

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:

  1. What if the given array is already sorted? How would you optimize your algorithm?
  2. What if nums1’s size is small compared to nums2’s size? Which algorithm is better?
  3. 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?

给定两个数组,编写一个函数来计算它们的交集。

注意
结果中的每个元素应该出现在两个数组中显示的次数。
结果可以是任何顺序。

跟进:

  1. 如果给定的数组已经排序怎么办? 你会如何优化算法?
  2. 如果nums1的尺寸与nums2的尺寸相比较小怎么办? 哪种算法更好?
  3. 如果nums2的元素存储在磁盘上,并且内存有限,以致您无法一次将所有元素加载到内存中,该怎么办?

2,题目思路

对于这道题,要求求出两个数组的交集。

说是求交集,其实就是求两个数组中相同的元素,交集是没有顺序之分的。在求解这个基础问题上,我们可以利用unordered_map来记录一个数组中出现的数字以及出现的次数,然后,再在另一个数组中进行一个遍历,找到在第二个数组中也出现的数字即可。

而当两个数组是有序的情况时,问题就变得简单了,因为两个数组的交集(如果存在的话)的元素一定是连在一起的。
于是,我们就可以使用“双指针法”来求解,即最开始两个指针指向两个数组的开头元素,如果值相等,就让这个元素的值加入到结果中,并让两个指针都向后移动一位;如果值不等,就让值较小的指针向后移动一位即可。

而对于内存问题:

  • 加入只有nums2无法完全存入内存,那么我们就以nums1构建hashMap,然后一部分一部分地将nums2放入内存中计算交集。
  • 而如果nums1和num2都无法放入内存中,此时我们可以对它们分别利用外部排序的办法进行排序,然后就想上面所说的数组有序的方法那样,一次读取两个元素的值,寻找交集。

3,代码实现

static auto speedup = [](){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return nullptr;
}();

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        unordered_map<int, int> hashMap;
        for(auto &n : nums1)
            hashMap[n]++;
        for(auto &n : nums2){
            if(--hashMap[n] >= 0)
                res.push_back(n);
        }        
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值