传送门:
136:https://leetcode-cn.com/probl...
56-I:https://leetcode-cn.com/probl...
对于第二题,问题看似简单,但是暗藏了“时间复杂度是O(n),空间复杂度是O(1)”这样的玄机。O(n)容易实现,但加上空间复杂度的要求就复杂得多。
考虑一下单个数的情况
即问题136,若只有一个只出现了一次的数字,该如何处理?
对于两个相同的数字,取异或后为0.同时任何数与0取异或为本身

1 0 1 1
1 0 1 1
0 0 0 0

将问题推广至两个不同的数
1.将所有数字取异或等于两个结果(r1,r2)的异或.
2.异或结果来看,从右往左按位搜索第一个1.这里的目的是将r1,r2从位上区分开。至于为什么从右往左,将异或结果转换为二进制---一直对2取余;另外也可以使用移位操作,那样从左从右都是一样的.
3.现在就可以按这一位将输入数组分为该位为0、该位为1两组。相同的数字一定会分在一个组,r1,r2一定分落在两个组.
4.对两组取异或分别得出r1,r2.

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int numXor = 0;
        //所有的异或,0^x = x
        for(int i=0;i<nums.size();++i)
            numXor ^= nums[i];
        int index=0;
        //取从右往左的第一个1
        for(;numXor%2==0;index++,numXor/=2);
        int a=0,b=0;
        for(int i=0;i<nums.size();++i){
            //按位右移index位.按该位分组
            if (((nums[i] >> index) & 1) == 0)
                a ^= nums[i];
            else
                b ^= nums[i];
        }
        return vector<int>{a, b};
    }
};

HHXXHGGZ
0 声望0 粉丝

« 上一篇
LeetCode 55
下一篇 »
LeetCode 1248