1. 程式人生 > >LeetCode 350. 兩個陣列的交集 II

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;
    }
};