[2]力扣每日一题

Posted tsuipo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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};
    }
};

以上是关于[2]力扣每日一题的主要内容,如果未能解决你的问题,请参考以下文章

[7]力扣每日一题

力扣每日一题——NO.142环形链表2

力扣每日一题 371. 两整数之和 (如何不用+和-让两数相加)

[2]力扣每日一题

力扣每日一题:按奇偶排序数组2

力扣 每日一题 518. 零钱兑换 II