• leetcode-349-Intersection of Two Arrays


    题目描述:

    Given two arrays, write a function to compute their intersection.

    Example:
    Given nums1 = [1, 2, 2, 1]nums2 = [2, 2], return [2].

    Note:

    1、Each element in the result must be unique.

    2、The result can be in any order.

     

    要完成的函数:

    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 

     

    说明:

    1、给定两个vector,求其交集。交集是一个集合,所以不能出现重复元素,集合不要求顺序。

    2、最直接的思路是模仿人类思维,设置两个set,分别存储nums1和nums2的数值。set中没有重复的元素,然后双重循环逐一比较,把相同的值写入结果的vector中。

    代码如下:

        vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
        {
            set<int>s1(nums1.begin(),nums1.end());
            set<int>s2(nums2.begin(),nums2.end());
            int size1=s1.size();
            int size2=s2.size();
            vector<int>res;
            if(size1<size2)
            {
                for(set<int>::iterator iter=s1.begin();iter!=s1.end();iter++)
                {
                    for(set<int>::iterator iter0=s2.begin();iter0!=s2.end();iter0++)
                    {
                        if(*iter==*iter0)
                        {
                            res.push_back(*iter);
                            break;
                        }
                    }
                }
            }
            else
            {
                for(set<int>::iterator iter=s2.begin();iter!=s2.end();iter++)
                {
                    for(set<int>::iterator iter0=s1.begin();iter0!=s1.end();iter0++)
                    {
                        if(*iter==*iter0)
                        {
                            res.push_back(*iter);
                            break;
                        }
                    }
                }
            }
            return res;
        }

    上述代码定义了两个set,把数据装入set,然后双重循环。实测16ms,在所有提交的样例中排名靠后。

    我们来看看能够怎样改进。

    3、改进1:

    我们同样定义两个set,把数据装入set,不过我们把双重循环改成单重循环+set.count(),也许利用内置函数会改善一点效果。(但其实单重循环+set.count()也是双重循环)

    代码如下:

        vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
        {
            set<int> s1(nums1.begin(),nums1.end());
            set<int> s2(nums2.begin(),nums2.end());
            vector<int>res;
            for(set<int>::iterator iter=s2.begin();iter!=s2.end();iter++)
            {
                if(s1.count(*iter))
                res.push_back(*iter);
            }
            return res;
        }

    代码简洁很多,实测下降到9ms,beats 46.70% of cpp submissions。

    看来set.count()这个函数效果还可以。

    4、改进2:

    我们能不能只定义一个set,然后依旧单重循环+set.count()。代码如下:

        vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
        {
            set<int> s1(nums1.begin(),nums1.end());
            vector<int>res;
            for(int i=0;i<nums2.size();i++)
            {
                if(s1.erase(nums2[i]))//如果s1中含有nums2{i},那么push到res中,并且把这个数从s1中删去,避免下一次处理到重复的数
                res.push_back(nums2[i]);
            }
            return res;
        }

    上述代码实测8ms,beats 70.98% of cpp submissions。

    省去了定义一个set和数据装入的过程,多了一点set删去数据的过程,这样子更省时间。

    5、改进3:

    在discuss区看到大神用了unordered_set,尝试了一下,代码如下:

        vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
        {
            unordered_set<int> s1(nums1.begin(),nums1.end());
            vector<int>res;
            for(int i=0;i<nums2.size();i++)
            {
                if(s1.erase(nums2[i]))
                res.push_back(nums2[i]);
            }
            return res;
        }

    上述代码实测7ms,beats 97.10% of cpp submissions,比起4中做法更省时。

    更省时间是因为set使用了红黑树作为存储的数据结构,unordered_set使用的是哈希表,不讲究顺序,而且哈希表读取数据速度更快。

    我们的输出不讲究顺序,只要求读取数据,所以使用unordered_set是一个更好的选择。

  • 相关阅读:
    Syn Bot /OSCOVA 基础教程(2)
    Syn Bot /OSCOVA 介绍(1)
    如何访问阿里云内网数据库
    Winform项目中的Settings.settings与App.config
    WinForm项目开发傻瓜教程
    C++读取BMP文件
    boost异步tcp通信技术练习
    lex/flex 学习笔记 一
    流数据解析中高位地址转换的性能分析
    bash随笔
  • 原文地址:https://www.cnblogs.com/chenjx85/p/8859248.html
Copyright © 2020-2023  润新知