LeetCode 350. 两个数组的交集 II

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

例如:
给定 nums1 = [1, 2, 2, 1]nums2 = [2, 2], 返回 [2, 2].

注意:

  •    输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  •    我们可以不考虑输出结果的顺序。

跟进:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?

思路:先排序,使用两个下标。如果数据过大不能一次性载入内存,有两种备选的处理方案,第一种是使用外部排序,依次载入比较,第二种是依次读入nums2,然后建立一个map,存贮nums2里面的数值和出现次数之间的关系,nums1,也做同样的处理,然后比较两个map

方法1:排序

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


方法2:map

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int> re;
        if(nums1.empty() || nums2.empty())
            return re;
        
        map<int, int> nums1map;
        map<int, int> nums2map;
        int i, j;
        for(i=0;i<nums1.size();++i){
            if(nums1map.count(nums1[i]))//说明存在这个数,加1
                nums1map[nums1[i]]++;
            else
                nums1map[nums1[i]]=1;
        }
        
        for(j=0;j<nums2.size();++j){
            if(nums2map.count(nums2[j]))//说明存在这个数,加1
                nums2map[nums2[j]]++;
            else
                nums2map[nums2[j]]=1;
        }
        
        map<int, int>::iterator iter1=nums1map.begin();
        map<int, int>::iterator iter2=nums2map.begin();
        int minTimes=0, minkey;
        while(iter1!=nums1map.end() and iter2!=nums2map.end()){
            if(iter1->first==iter2->first){
                minkey = (iter1->second < iter2->second)? iter1->first:iter2->first;
                minTimes = (iter1->second < iter2->second)? iter1->second:iter2->second;
                for(i=0;i<minTimes;++i)
                    re.push_back(minkey);
                
                iter1++;
                iter2++;
            }
            else if(iter1->first > iter2->first)
                iter2++;
            else
                iter1++;
        }
        
        return re;
    }
};

猜你喜欢

转载自blog.csdn.net/sinat_15723179/article/details/80885375