350. 两个数组的交集 II

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]

说明:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  • 我们可以不考虑输出结果的顺序。

进阶:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

思路:

法一:

和版本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 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

对于法一,它需要对所有元素进行排序,所以不适用

对于法二和法三,数据的先后顺序对它们影响不大,所以它们可以先从内存取一部分数据,再处理数据,再取数据再处理,直到数据处理完为止

你可能感兴趣的:(Leetcode,Leetcode带思路)