数组中只出现一次的两个数

剑指 Offer 56 - I. 数组中数字出现的次数

大意:找出数组中只出现一次的两个数(其它出现两次)

思路 & 代码 思路:首先需要知道一个前置问题:找出数组中只出现一次的一个数(其它出现两次),显然,对整个数组进行异或操作即可。那么,我们是否有可能将本题中的数组分隔成两部分呢(不要求连续)?答案是肯定的:我们仍然对整个数组进行异或操作,结果记为 xorS(两个特殊的数的异或值),注意到 xorS 中的每一位 1 都只属于两个特殊数中的某一个,记最低位为 lowNoZeorBit,所以这里以数组中 lowNoZeroBit 位是否为 1 为界限,可将数组分隔成两部分,且这两部分异或值即为最终的两个特殊的数

时间:O(n),空间:O(1)

class Solution {
    public int getLowNoZeroBit(int s) {
        int bit = 0;
        // 区别于「快速幂」
        while(s > 0) {
            bit++;
            if((s&1) == 1) break;
            s >>= 1;
        }
        return bit;
    }
    
    public int[] singleNumbers(int[] nums) {
        int xorS = 0;
        for(int num : nums) xorS ^= num;
        int lowNoZeroBit = getLowNoZeroBit(xorS);
        /*
        0010 
        1010
        System.out.println(lowNoZeroBit); // 4
        */
        int[] ans = new int[2];
        for(int num : nums) {
            ans[(num >> (lowNoZeroBit-1)) & 1] ^= num;
        }
        return ans;
    }
}
posted @ 2020-12-02 18:28  我在这儿  阅读(181)  评论(0编辑  收藏  举报