[LeetCode]350. Intersection of Two Arrays II(求两个数组交集 II)

350. Intersection of Two Arrays II

点击查看349. Intersection of Two Arrays

原题链接
Given two arrays, write a function to compute their intersection.
给两个数组,写一个函数求交集
Example:

Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].

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?
  • 如果nums1的规模相比,nums2尺寸小?哪种算法比较好?
  • 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?
  • 如果元素的nums2存储在磁盘上,而记忆是有限的,你无法加载所有的元素进记忆呢?

思路1:

代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        if(nums1.empty() || nums2.empty())
            return res;
        vector<int>& NUMS1 = nums1;
        vector<int>& NUMS2 = nums2;
        sort(NUMS1.begin(), NUMS1.end());
        sort(NUMS2.begin(), NUMS2.end());

        for(int i=0,j=0; i<NUMS1.size()&&j<NUMS2.size();){
            if(NUMS1[i] == NUMS2[j]){
                res.push_back(NUMS1[i]);
                i++;j++;
                continue;
            }
            else if(NUMS1[i] > NUMS2[j]){
                j++;
            }
            else{
                i++;
            }
        }
        return res;
    }
};
int main()
{
    Solution a;
    int num1[] = {1, 2, 2, 1};
    int num2[] = {2, 2};
    vector<int> nums1(num1, num1 + sizeof(num1)/sizeof(num1[0]));
    vector<int> nums2(num2, num2 + sizeof(num2)/sizeof(num2[0]));
    vector<int> res = a.intersect(nums1, nums2);
    for(int i=0; i<res.size(); i++){
        cout << res[i] << " ";
    }
    return 0;
}

思路2:

  • 根据进一步思考的内容,相处了用hash表的方法,比较简单直接贴出代码
  • 如果是有序的可以不用hash表, 同时扫描两个数组, 找相同的.
  • 如果nums2在磁盘中, 用hash表无影响
    代码如下:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        if(nums1.size()==0 || nums2.size()==0)
                return vector<int>();
        vector<int> res;
        unordered_map<int, int> HASH;
        for(auto val1: nums1)
            HASH[val1]++;
        for(auto val2: nums2){
            if(HASH.count(val2) && HASH[val2]>0)
                res.push_back(val2);
            HASH[val2]--;
        }
         return res;
     }
  1. 如果不排序,O(mn)。
  2. 如果m和n都在合理范围内,先排序,再一个一个对比,时间复杂度O(nlgn + mlgm + m+n)。
  3. 如果m远小于n, 对n排序,m也排序(nlgn+mlgm+m+n),或者m不排序(nlgn + mn)。 这两种都差不多。也可以对m不排序,在n里做binary search(二叉查找),这样复杂度降低为nlgn+mlgn, 降很低。
  4. 如果n很大,n只能存在disk上。只能把m load到内存,然后n一个一个的读进来,和m对比,这时m可以用hash存,这样复杂度就为O(n)了。
  5. 以上结论参考点击查看
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值