两个数组的交集II。题意跟349题几乎一样,唯一的区别在于349题请输出unique的交集,但是本题请输出所有的交集,所以需要考虑重复数字的情况。例子,
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]
两种做法,一是hashmap,二是双指针。
hashmap的做法是先扫描num1,记录每个数字和他们出现的次数;再遍历num2,如果在hashmap里出现了相同的key则value--,但是注意判断的方式不是if (map.containsKey(x)),而是判断这个key背后的value是否大于0,因为之后要对value--。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int[] intersect(int[] nums1, int[] nums2) { 3 HashMapmap = new HashMap<>(); 4 List list = new ArrayList<>(); 5 for (int num : nums1) { 6 if (map.containsKey(num)) { 7 map.put(num, map.get(num) + 1); 8 } else { 9 map.put(num, 1); 10 } 11 } 12 for (int num : nums2) { 13 if (map.containsKey(num)) { 14 if (map.get(num) > 0) { 15 list.add(num); 16 map.put(num, map.get(num) - 1); 17 } 18 } 19 } 20 int[] res = new int[list.size()]; 21 int k = 0; 22 for (int num : list) { 23 res[k++] = num; 24 } 25 return res; 26 } 27 }
JavaScript实现
1 /** 2 * @param {number[]} nums1 3 * @param {number[]} nums2 4 * @return {number[]} 5 */ 6 var intersect = function(nums1, nums2) { 7 let map = new Map(); 8 let list = []; 9 for (let num of nums1) { 10 if (map.has(num)) { 11 map.set(num, map.get(num) + 1); 12 } else { 13 map.set(num, 1); 14 } 15 } 16 for (let num of nums2) { 17 if (map.get(num) > 0) { 18 list.push(num); 19 map.set(num, map.get(num) - 1); 20 } 21 } 22 return list; 23 };
双指针的做法是先sort两个数组然后逐个比较,看两边遍历到的元素是否一样,若是则加入结果集。
时间O(nlogn) - sort
空间O(n)
Java实现ONLY
1 class Solution { 2 public int[] intersect(int[] nums1, int[] nums2) { 3 Arrays.sort(nums1); 4 Arrays.sort(nums2); 5 Listlist = new ArrayList<>(); 6 int i = 0; 7 int j = 0; 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 list.add(nums1[i]); 15 i++; 16 j++; 17 } 18 } 19 int[] res = new int[list.size()]; 20 int k = 0; 21 for (int num : list) { 22 res[k++] = num; 23 } 24 return res; 25 } 26 }