给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]
示例 2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]
说明:
进阶:
思路:
法一:
和版本I的第2种方法差不多,在版本I的法2基础上去掉删除重复元素的步骤就可以
代码:
class Solution {
public:
vector intersect(vector& nums1, vector& nums2) {
vector rev;
if(nums1.empty() ||nums2.empty()) //如果数组其中一个为空,直接返回空数组
return rev;
sort(nums1.begin(),nums1.end()); //将数组1排序
sort(nums2.begin(),nums2.end()); //将数组2排序
vector::iterator n1=nums1.begin(),n2=nums2.begin(); //设定指针n1和n2
while(n1*n2 && n2*n2的情况
n2++;
while(*n1<*n2 &&n1
法二:
由于要考虑 nums1 的大小比 nums2 小很多的情况,所以假设在这样的情况下,我们可以直接对nums1的每个元素遍历nums2,这样最差需要花费(nums1.size()*nums2.size())的时间
法三:
也是考虑 nums1 的大小比 nums2 小很多的情况
用一个map存数组1中元素的个数,将元素作为key,元素的个数作为value
然后遍历数组2,如果数组2中元素的映射大于等于1,则将元素放到要返回的数组,并将映射减1
代码:
class Solution {
public:
vector intersect(vector& nums1, vector& nums2) {
map m;
for(int i=0;i rev;
for(int i=0;i=1) //映射大于等于1的情况
{
rev.push_back(nums2[i]);
m[nums2[i]]--;
}
}
return rev;
}
};
如果给定的数组已经排好序呢?你将如何优化你的算法?
法二和法三没得优化
对于法一,则是增强了它的数据规模处理性,使得在不能一次加载所有的元素到内存中这种情况下法一也可行
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
法一在此情况下会有多余的排序,比如说nums1的长度是1,nums2的长度是1000000,那么会浪费排序的时间
法二在此情况下就比较不错了,因为nums1的长度小,所以综合不会花很多时间,但法二仅是适用于这种情况,在其它情况下就是蛮力法,是很糟糕的
法三无论是在正常情况,还是在上面这种极端情况,速度都比较快的
所以总的来说,在上面这种极端情况下,法二和法三更优
如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
对于法一,它需要对所有元素进行排序,所以不适用
对于法二和法三,数据的先后顺序对它们影响不大,所以它们可以先从内存取一部分数据,再处理数据,再取数据再处理,直到数据处理完为止