LeetCode350

两个数组的交际2

1. 题目描述

给你两个整数数组nums1和nums2,请你以数组的形式返回两数组的交集。返回结果中每个元素出现的次数,英语元素在两个数组中都出现的次数一致。可以不考虑输出结果的顺序。

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

2. 解法

2.1 我的解法-双map

一开始我的思路是:我想要统计每个数组中每个元素出现的次数,然后对比这两份统计结果,取其中较小的次数填入答案。

由于要统计元素出现的次数,我想到了map或者数组。以示例为例,定义空的map1和map2。首先遍历nums1,nums1中元素代表map1中的key值,遍历到了,就在map1对应key处加1.所以遍历完两个数组后map1=[2,2],map2=[0,2]。然后对比两张map,在都有value的地方选取较小的value作为交集中该key出现的次数填入交集。

在这里插入图片描述

代码如下:

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) 
    {
        vector<int> ans;
        map<int,int> m1, m2;
        for(int r:nums1)//遍历nums,统计各元素出现的次数
        {
            ++m1[r];
        } 
        for(int r:nums2)
        {
            ++m2[r];
        }
        for(int i=0;i!=(m1.size()<m2.size()?m1.size():m2.size());++i)//循环次数为m中大小较小的值
        {
            m1[i]=m1[i]<m2[i]?m1[i]:m2[i];//只选取较小的值保留下来
            if(m1[i])//如果m[i]处value不为0
            {
                for(int j=0;j!=m1[i];++j)以该value为次数填入数据
                {
                    ans.push_back(i);
                }
            }
        }
        return ans;
    }
};

执行用时16ms,内存消耗12.1MB。

2.2 单map,优化一下

如果我只统计一个数组中元素出现的次数,然后遍历另一个数组,以这个数组的元素值为key搜索map。如果map[key]不为0,就代表这两个数组出现了重复元素一次。这个时候–map[key],将key添加进答案,不就完成这道题了吗?第一次遍历的数组可以选取长度较短的数组。

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) 
    {
        if(nums1.size()>nums2.size()) return intersect(nums2,nums1);//选取较短的数组作为第一个参数
        vector<int> ans;
        map<int,int> m1;
        for(int r:nums1)
        {
            ++m1[r];
        } 
        for(int r:nums2)
        {
            if(m1.find(r)->second)
            {
                ans.push_back(r);
                --m1[r];
            }
        }
        return ans;
    }
};

执行用时4ms,内存消耗10.2MB。

2.3 双指针

这里双指针用法与之前类似。之前是快慢指针,在同一个数组中,这里换成了不同数组。首先将两个数组排序。定义两个指针分别指向两个数组的起始位置。解引用指针判断是否相等,相等的话就将该值填入答案,然后两个指针均+1;不等的话,指向较小值的指针++,另一个不动。结束循环的条件为其中一个指针指向了end()。

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) 
    {
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());
        vector<int>::iterator it1 = nums1.begin(), it2 = nums2.begin();
        vector<int> ans;
        while(it1!=nums1.end() && it2!=nums2.end())
        {
            if(*it1 == *it2)
            {
                ans.push_back(*it1);
                ++it1;
                ++it2;
            }
            else
            {
                *it1 < *it2 ? ++it1 : ++it2;
            }
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值