题目:
Given two arrays, write a function to compute their intersection.
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]
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?
第一个想到的办法就是存hashmap,计算出每个数字在每个数组里出现的次数,然后遍历一遍hashmap把两边同时出现的数字取出现次数最小的次数加入result就可以了。时间复杂度O(max(m ,n))吧。看了解答其实不需要两个map,直接第一个map存完后在遍历nums2的时候查它在不在map里就行了。以下是第一次做时的两个map解法。
Runtime: 3 ms, faster than 43.83% of Java online submissions for Intersection of Two Arrays II.
Memory Usage: 39.6 MB, less than 15.22% of Java online submissions for Intersection of Two Arrays II.
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
List<Integer> result = new ArrayList<>();
Map<Integer, Integer> map1 = new HashMap<>();
Map<Integer, Integer> map2 = new HashMap<>();
for (int i : nums1) {
map1.put(i, map1.getOrDefault(i, 0) + 1);
}
for (int i : nums2) {
map2.put(i, map2.getOrDefault(i, 0) + 1);
}
for (Map.Entry<Integer, Integer> entry : map1.entrySet()) {
int key = entry.getKey();
if (map2.containsKey(key)) {
int value = Math.min(entry.getValue(), map2.get(key));
for (int i = 0; i < value; i++) {
result.add(key);
}
}
}
int[] resultArray = new int[result.size()];
for (int i = 0; i < result.size(); i++) {
resultArray[i] = result.get(i);
}
return resultArray;
}
}
2022.10.25来补上了优化后的代码。
Runtime: 6 ms, faster than 52.22% of Java online submissions for Intersection of Two Arrays II.
Memory Usage: 44.7 MB, less than 7.72% of Java online submissions for Intersection of Two Arrays II.
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
return nums1.length < nums2.length ? findIntersectInMap(nums2, getMap(nums1)) : findIntersectInMap(nums1, getMap(nums2));
}
private Map<Integer, Integer> getMap(int[] nums) {
Map<Integer, Integer> result = new HashMap<>();
for (int i : nums) {
result.put(i, result.getOrDefault(i, 0) + 1);
}
return result;
}
private int[] findIntersectInMap(int[] nums, Map<Integer, Integer> map) {
List<Integer> list = new ArrayList<>();
for (int i : nums) {
if (map.containsKey(i) && map.get(i) > 0) {
list.add(i); // add the num to the list each time until it counts down to 0
map.put(i, map.get(i) - 1);
}
}
int[] result = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
result[i] = list.get(i);
}
return result;
}
}
针对Follow up 1:What if the given array is already sorted? How would you optimize your algorithm?
也可以先sort完了以后用two pointers O(n)一次解决。刚开始不知道为啥可能受了刚刚做duplicate的影响所以以为要整duplicate就写的很麻烦(被注释掉的部分),后来看了解答才发现想多了orz。
Runtime: 2 ms, faster than 96.63% of Java online submissions for Intersection of Two Arrays II.
Memory Usage: 39.2 MB, less than 15.22% of Java online submissions for Intersection of Two Arrays II.
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int p1 = 0;
int p2 = 0;
List<Integer> result = new ArrayList<>();
while (p1 != nums1.length && p2 != nums2.length) {
if (nums1[p1] < nums2[p2]) {
p1++;
} else if (nums1[p1] > nums2[p2]) {
p2++;
} else {
/*int count1 = 1;
while (p1 + 1 != nums1.length && nums1[p1] == nums1[p1 + 1]) {
p1++;
count1++;
}
int count2 = 1;
while (p2 + 1 != nums2.length && nums2[p2] == nums2[p2 + 1]) {
p2++;
count2++;
}
int count = Math.min(count1, count2);
for (int i = 0; i < count; i++) {
result.add(nums1[p1]);
}*/
result.add(nums1[p1]);
p1++;
p2++;
}
}
int[] resultArray = new int[result.size()];
for (int i = 0; i < result.size(); i++) {
resultArray[i] = result.get(i);
}
return resultArray;
}
}
2022.10.25代码写的跟上面一模一样,就是没有像上面那样被别的题影响于是想多了。
Runtime: 4 ms, faster than 80.25% of Java online submissions for Intersection of Two Arrays II.
Memory Usage: 44 MB, less than 47.11% of Java online submissions for Intersection of Two Arrays II.
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int p1 = 0;
int p2 = 0;
List<Integer> list = new ArrayList<>();
while (p1 < nums1.length && p2 < nums2.length) {
if (nums1[p1] < nums2[p2]) {
p1++;
} else if (nums1[p1] > nums2[p2]) {
p2++;
} else {
list.add(nums1[p1]);
p1++;
p2++;
}
}
int[] result = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
result[i] = list.get(i);
}
return result;
}
}
其他follow up可以参考:Loading...