Leetcode 初级算法:数组6.两个数组的交集 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 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

初步想法:先对nums1,nums2进行排序,再对nums1进行消除重复元素后,再与nums2进行比较相同的返回,但是这种没有考虑到nums1中有的元素只有一个,但是会在nums2中存在两次的问题,导致nums2输出两次如:
 1  2 3
 1 1 2 3 4
 应输出1 2 3 而实际输出却为1 1 2 3
 代码如下:
 

```cpp
class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        int i,n=0,m=0;
        vector<int> resVec;
        resVec.clear();
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());//先对两个容器进行排序
        for(i=0;i<nums1.size();i++){
            if(nums1[i]!=nums1[n]){
                n++;
                nums1[n]=nums1[i];
            }//将nums1进行去重复数字,再用其中数字和nums2中的依次比较
        }
        for(i=0;i<n+1;i++){
            for(int j=0;j<nums2.size();j++){
                if(nums1[i]==nums2[j]){
                    resVec.push_back(nums2[j]);
                    m++;
                }
            }
        }
        return resVec;
    }
};
```
经修改后代码如下:
想法是先对数组排序,然后进行对比,中间出现了数组越界问题,因为size得到的是长度,实际上下标只能到达size-1的地方
想法实现:
1 2 3 3 4  n
2 2 3 4 4 5  m
先1 2对比因为1小于2,所以n向后移动一位,2 2相等所以m,n各加一,3大于2 所以m向后移动一位 在这一过程中使用resVec.push_back()将相同的数字插入resVec中
意外情况:
1.没有考虑到一个数只能比较一次,不能与其他数进行重复比较,所以到最后一个数字时,已经无需再次比较直接break即可
```cpp
class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        int i,n=0,m=0;
        vector<int> resVec;
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());//先对两个容器进行排序
        while(n<nums1.size() && m<nums2.size()){
            if(nums1[n]==nums2[m]){//有相同数字时
                resVec.push_back(nums1[n]);//将这个数字返回到resVec中
                if(n==nums1.size()-1 &&m==nums2.size()-1){//此时个容器都已经排了最后一个可以直接退出了
                break;
            }
                if(n<nums1.size()-1 && m<nums2.size()-1){//说明两个容器还没到最后一个如果相同下标继续向后移动即可
                    n++;
                    m++;
                }
                else if(n==nums1.size()-1 &&m<nums2.size()-1){//nums1已经到了最后一个数,不必再比较
                    break;
                }
                else if(n<nums1.size()-1 &&m==nums2.size()-1){//nums2已经到了最后一个数,不必再比较
                    break;
                }
            }
            else if(nums1[n]>nums2[m]){//因为已经对nums1,nums2排过序,说明nums2此时的值小于nums1,m向后移动一位
                m++;
            }
            else if(nums1[n]<nums2[m]){
                n++;
            }
        }
        return resVec;
    }
    }
    ```
如果说数组是有序数组,则我们不必对其进行排序直接比较即可
代码如下:

```cpp
class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        int i,n=0,m=0;
        vector<int> resVec;
        while(n<nums1.size() && m<nums2.size()){
            if(nums1[n]==nums2[m]){//有相同数字时
                resVec.push_back(nums1[n]);//将这个数字返回到resVec中
                if(n==nums1.size()-1 &&m==nums2.size()-1){//此时个容器都已经排了最后一个可以直接退出了
                break;
            }
                if(n<nums1.size()-1 && m<nums2.size()-1){//说明两个容器还没到最后一个如果相同下标继续向后移动即可
                    n++;
                    m++;
                }
                else if(n==nums1.size()-1 &&m<nums2.size()-1){//nums1已经到了最后一个数,不必再比较
                    break;
                }
                else if(n<nums1.size()-1 &&m==nums2.size()-1){//nums2已经到了最后一个数,不必再比较
                    break;
                }
            }
            else if(nums1[n]>nums2[m]){//因为已经对nums1,nums2排过序,说明nums2此时的值小于nums1,m向后移动一位
                m++;
            }
            else if(nums1[n]<nums2[m]){
                n++;
            }
        }
        return resVec;
    }
    }
```

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值