来自力扣第350题两个数组的交集II
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
1 2
| 输入:nums1 = , nums2 = 输出:
|
哈希map
常规写法,用一个map存储两个数组中较短数组的元素,以及次数,接着遍历第二个数组,判断第二个数组里的元素是否存在于map里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public int[] intersect(int[] nums1, int[] nums2) { if(nums1.length > nums2.length) return intersect(nums2,nums1); HashMap<Integer,Integer> map = new HashMap<>(); for (int value : nums1) { map.put(value, map.getOrDefault(value, 0) + 1); } List<Integer> ans = new ArrayList<>(); for(int value : nums2){ int a = map.getOrDefault(value,0); if(a > 0){ ans.add(value); map.put(value,a-1); } } int[] res = new int[ans.size()]; for(int i = 0 ; i < ans.size() ; i++) res[i] = ans.get(i); return res; }
|
双指针
太久没写题了,都忘记还有排序后双指针的做法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public int[] intersect(int[] nums1, int[] nums2) { Arrays.sort(nums1); Arrays.sort(nums2); int i = 0, j = 0, k = 0; while (i < nums1.length && j < nums2.length) { if(nums1[i] < nums2[j]) { i++; } else if (nums1[i] > nums2[j]) { j++; } else { nums1[k++] = nums1[i]; i++; j++; } } return Arrays.copyOfRange(nums1, 0, k); }
|
另类哈希
找执行用时范例里看到的,本质上也是一种hash,只不过事先预设或找出测试用例里最大的元素值,那么这样对其求余即可,用数组作为哈希表,提升了运行时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| private final int MAGIC = 1000; public int[] intersect(int[] nums1, int[] nums2) { int j = 0; int freq[] = new int[MAGIC]; for (int i = 0; i < nums1.length; i++) { freq[Math.abs(nums1[i] % MAGIC)]++; } int res[] = new int[nums1.length]; for (int i = 0; i < nums2.length; i++) { if (freq[Math.abs(nums2[i] % MAGIC)]-- > 0) { res[j++] = nums2[i]; } } return Arrays.copyOf(res, j); }
|