[2]力扣每日一题

2020.4.28数组中数字出现的次数

题目呈现如下:

题干
题目传送门

思路介绍:

我们知道,两个相同的数字进行^操作,得0.假设本题中只出现一次的数字分别为a和b.
那末,在本题中全体数字取^将得到什么呢?没错,是a^b.我们算法的思想是完成以下两条:

  • 0.一开始有两个空篮子
  • 1.将a和b必须被放入不同的两个篮子里面
  • 2.相同的数字一定要被在一个篮子里面
    如何完成上面的2?你是不是可以把除了a和b的全部数字放到一个篮子?大于或者小于0可不可以作为分类标准?与1按位取&是否可以为分类标准?都可以!所以想想如何满足1.
    a和b如何区分呢?只要找到a与b二进制中不同的一位即可.假设\(x_{i}\)\(y_{i}\)分别是a和b从右往左数的第i+1位(低位下标为0),那么\(x_{i}\)&\(y_{i}\)=1.所以问题核心在找到这个下标i.具体方法请看以下代码😉

下附AC代码

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int a = 0, b = 0; // a和b是只出现一次的数字,先初始化为0
        int rt = 0;
        for(auto i:nums) {
            rt ^= i; // 全体取亦或,相同的数字亦或和为0.那末,最后的结果就是所求的两个数字的亦或
        }            // ①其中的某位如果为1,说明a与b的这一位是不同的
        int divid = 1; // 二进制形式为0000..1
        while((divid & rt) == 0) divid <<= 1; // 0000..0001 -> 0000..0010 -> 0000..0100 ...
        for(auto i:nums) {                    // 直至找到divid为1这位正好对准rt中为1的那一位
            if(divid & i) a ^= i;             // rt某位为1的意义👆见标注①
            else b ^= i;
        }
        return vector<int>{a,b};
    }
};
posted @ 2020-04-28 23:52  俺,TSUI!  阅读(147)  评论(1编辑  收藏  举报