*Single Number III

这题真特么是太难了

 

 

解题思路

首先我们先把原数组全部异或起来,那么我们会得到一个数字,这个数字是两个不相同的数字异或的结果,我们取出其中任意一位为‘1’的位,为了方便起见,我们用 a &= -a 来取出最右端为‘1’的位。。。这道题的巧妙之处在于利用x1 ^ x2的结果对原数组进行了分组,进而将x1x2分开了。具体方法则是利用了x1 ^ x2不为0的特性,如果x1 ^ x2不为0,那么x1 ^ x2的结果必然存在某一二进制位不为0(即为1),我们不妨将最低位的1提取出来,由于在这一二进制位上x1x2必然相异,即x1x2中相应位一个为0,另一个为1,所以我们可以利用这个最低位的1将x1x2分开。又由于除了x1x2之外其他数都是成对出现,故与最低位的1异或时一定会抵消,十分之精妙!

首先计算nums数组中所有数字的异或,记为xor
令lowbit = xor & -xor,lowbit的含义为xor从低位向高位,第一个非0位所对应的数字

例如假设xor = 6(二进制:0110),则-xor为(二进制:1010,-6的补码,two's complement)

则lowbit = 2(二进制:0010)

public class Solution {
    public int[] singleNumber(int[] nums) {
        int xor = 0;
        
        for(int i=0;i<nums.length;i++)
        {
            xor = xor ^ nums[i];
        }
        
        int lowBit = xor & (-xor);
        
        int[] singles = new int[2];
        for(int i=0;i<nums.length;i++)
        {
            if((nums[i]&lowBit)==0)
            {
                singles[0] = singles[0]^nums[i];
            }
            else
            {
                singles[1] = singles[1]^nums[i];
            }
        }
        return singles;
        
    }
}
reference:
http://www.cnblogs.com/grandyang/p/4741122.html
http://bookshadow.com/weblog/2015/08/17/leetcode-single-number-iii/
http://www.kancloud.cn/kancloud/data-structure-and-algorithm-notes/72983

 

posted @ 2016-08-10 10:41  Hygeia  阅读(152)  评论(0)    收藏  举报