LeetCode 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:
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?
    • 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?

题解:

可以使用双指针.

Time Complexity: O(nlogn). Space: O(1).

AC Java:

 1 public class Solution {
 2     public int[] intersect(int[] nums1, int[] nums2) {
 3         Arrays.sort(nums1);
 4         Arrays.sort(nums2);
 5         int i = 0;
 6         int j = 0;
 7         List<Integer> res = new ArrayList<Integer>();
 8         while(i<nums1.length && j<nums2.length){
 9             if(nums1[i] < nums2[j]){
10                 i++;
11             }else if(nums1[i] > nums2[j]){
12                 j++;
13             }else{
14                 res.add(nums1[i]);
15                 i++;
16                 j++;
17             }
18         }
19         
20         int [] resArr = new int[res.size()];
21         int k = 0;
22         for(int num : res){
23             resArr[k++] = num;
24         }
25         return resArr;
26     }
27 }

AC C++:

 1 class Solution {
 2 public:
 3     vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
 4         vector<int> res;
 5         sort(nums1.begin(), nums1.end());
 6         sort(nums2.begin(), nums2.end());
 7         int len1 = nums1.size();
 8         int len2 = nums2.size();
 9         int i = 0;
10         int j = 0;
11         while(i < len1 && j < len2){
12             if(nums1[i] < nums2[j]){
13                 i++;
14             }else if(nums1[i] > nums2[j]){
15                 j++;
16             }else{
17                 res.push_back(nums1[i]);
18                 i++;
19                 j++;
20             }
21         }
22 
23         return res;
24     }
25 };

Could use HashMap as well.

Time Complexity: O(m + n).

Space: O(Math.min(m, n)).

AC Java:

 1 class Solution {
 2     public int[] intersect(int[] nums1, int[] nums2) {
 3         if(nums1 == null || nums2 == null){
 4             return new int[0];
 5         }
 6         
 7         HashMap<Integer, Integer> hm = new HashMap<>();
 8         for(int num : nums1){
 9             hm.put(num, hm.getOrDefault(num, 0) + 1);
10         }
11         
12         List<Integer> res = new ArrayList<>();
13         for(int num : nums2){
14             if(hm.containsKey(num)){
15                 res.add(num);
16                 if(hm.get(num) == 1){
17                     hm.remove(num);
18                 }else{
19                     hm.put(num, hm.get(num) - 1);
20                 }
21             }
22         }
23         
24         int [] resArr = new int[res.size()];
25         int i = 0;
26         for(int num : res){
27             resArr[i++] = num;
28         }
29         
30         return resArr;
31     }
32 }

AC C++:

 1 class Solution {
 2 public:
 3     vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
 4         vector<int> res;
 5         unordered_map<int, int> map;
 6         for(int num : nums1){
 7             map[num]++;
 8         }
 9 
10         for(int num : nums2){
11             if(map[num] > 0){
12                 res.push_back(num);
13                 map[num]--;
14             }
15         }
16 
17         return res;
18     }
19 };

Follow up 2 nums1 length is smaller. 用双指针先sort两个array明显没有利用到num1.length小的特性. 若是用HashMap来记录num1每个element出现频率再iterate nums2, 那么Time Complexity: O(m + n), m = nums1.length, n = num2.length. Space: O(m).

或者sort nums1 再对每一个num2的element在 sorted nums1上做 binary search. Time Complexity: O(mlogm + nlogm). Space: O(1).

由此可见,当m很小时,用HashMap和binary search就是time和space的trade off.

 

Follow up 3 nums2 is sorted but too big for memory. I/O的操作很贵,所以首先想到的是避免I/O的次数。

若是nums1可以全部load到memory上, 先sort nums1再把nums2从小到大分开load到memory来.

  if load进来这一段最大值, 也就是最后一个值<nums1[0] 或者 load进来这一段最小值, 也就是第一个值>nums1[nums1.length-1]可以直接跳过, load下一段.   else load进来这一段 和 sorted nums1做双指针.

若是nums1也太大了,就先external sort nums1, 在分开load进来nums1一段和nums2一段做双指针.

类似Find Common CharactersIntersection of Two Arrays.

posted @ 2017-01-06 10:10  Dylan_Java_NYC  阅读(210)  评论(0编辑  收藏  举报