美文网首页
LC260 Single Number III

LC260 Single Number III

作者: Rookie118 | 来源:发表于2020-06-26 22:29 被阅读0次

    本题链接:Single Number III

    本题标签:Bit Manipulation

    本题难度:\color{Orange}{Medium}

    英文题目 中文题目

    本题是136.Single Number的升级版。

    方案1: 利用LC136的思路

    根据LC136的思路,我们可以得到两个只出现一次的数字的异或结果,即例子中的3 \oplus 5。现在我们只要能将这个异或结果分离出来就能得到答案。那么我们可以从二进制的角度考虑,3 \oplus 5 = (0011) \oplus (0101) = 0110 = 6

    这里可以发现异或运算保留的是两个数不同的部分,若我们可以将0110 中最右边的1 取出来组成 0010,而这个0010就是数字3和数字5不同的部分,这样我们就可以通过和nums中的数进行二进制与运算是否为0来将nums划分为两部分,一部分包含了数字3和其他重复数字,另一部分包含了数字5和其他重复数字。

    这个0010 我们可以通过异或结果3 \oplus 5 = 0110 = 6与自己的负数进行二进制与运算得到,即6 \cdot (-6) = (0110) \cdot (1010) = 0010 = 2。因为一个数的负数二进制形式是对这个数按位取反再加1,也就是补码形式。

    class Solution {
    public:
        vector<int> singleNumber(vector<int>& nums) {
            vector<int> res(2, 0);
            int diff = 0;
            for(int n : nums)
                diff = diff ^ n;
            diff = diff & (-diff); // 这里是为了保留diff中最右边为1的二进制位
            
            for(int n : nums)
            {
                if((n & diff) == 0)  // 根据与diff按位与是否为0将数组划分为两部分,
                                     // 这两部分各自包含一个只出现1次的数字
                    res[0] = res[0] ^ n;
                else
                    res[1] = res[1] ^ n;
            }
            return res;
        }
    };
    

    时间复杂度:O ( N )

    空间复杂度:O ( 1 )


    相关文章

      网友评论

          本文标题:LC260 Single Number III

          本文链接:https://www.haomeiwen.com/subject/ixlpfktx.html