1,题目要求
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?
给定两个数组,编写一个函数来计算它们的交集。
注意:
结果中的每个元素应该出现在两个数组中显示的次数。
结果可以是任何顺序。
跟进:
- 如果给定的数组已经排序怎么办? 你会如何优化算法?
- 如果nums1的尺寸与nums2的尺寸相比较小怎么办? 哪种算法更好?
- 如果nums2的元素存储在磁盘上,并且内存有限,以致您无法一次将所有元素加载到内存中,该怎么办?
2,题目思路
对于这道题,要求求出两个数组的交集。
说是求交集,其实就是求两个数组中相同的元素,交集是没有顺序之分的。在求解这个基础问题上,我们可以利用unordered_map来记录一个数组中出现的数字以及出现的次数,然后,再在另一个数组中进行一个遍历,找到在第二个数组中也出现的数字即可。
而当两个数组是有序的情况时,问题就变得简单了,因为两个数组的交集(如果存在的话)的元素一定是连在一起的。
于是,我们就可以使用“双指针法”来求解,即最开始两个指针指向两个数组的开头元素,如果值相等,就让这个元素的值加入到结果中,并让两个指针都向后移动一位;如果值不等,就让值较小的指针向后移动一位即可。
而对于内存问题:
- 加入只有nums2无法完全存入内存,那么我们就以nums1构建hashMap,然后一部分一部分地将nums2放入内存中计算交集。
- 而如果nums1和num2都无法放入内存中,此时我们可以对它们分别利用外部排序的办法进行排序,然后就想上面所说的数组有序的方法那样,一次读取两个元素的值,寻找交集。
3,代码实现
static auto speedup = [](){
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int> res;
unordered_map<int, int> hashMap;
for(auto &n : nums1)
hashMap[n]++;
for(auto &n : nums2){
if(--hashMap[n] >= 0)
res.push_back(n);
}
return res;
}
};