[LeetCode] 260. Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

Example:

Input:  [1,2,1,3,2,5]
Output: [3,5]

Note:

  • The order of the result is not important. So in the above example, [5, 3] is also correct.
  • Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

这道题做法很巧妙,首先对于nums进行一轮异或操作,这样最后就得到了两个唯一的ab的异或的值,即eor=a^b, 现在需要能分开a和b,具体的做法是这样,首先算出eor最右边的为1其余为0的值,这个算法是N&(~N+1)。其实nums里的值分成两组,一组是在这个位置上为1,一组是在这个位置上为0,但有一点可以肯定,a和b一定分属于两个组,不然不可能在这个位置上异或为1。所以可以再一次循环数组,然后和这个只有1位唯一1其余为0的数进行与操作,如果得到值不等于这个值,那么这个值在这个位置上就为0,把这些在这个位置上为0的数进行异或操作。那么得到的肯定就是a或b。最后在把这个值和eor异或一下。就得到另一个值了。

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        if not nums or len(nums) <= 2: return nums
        eor, eor1 = 0, 0
        for num in nums:
            eor ^= num
       
        right_one = eor & (~eor + 1)
        for num in nums:
            if (num & right_one) != right_one:
                eor1 ^= num
        
        eor ^= eor1
        return [eor, eor1]

java的写法

class Solution {
public:
    /**
     * @param A : An integer array
     * @return : Two integers
     */
    vector<int> singleNumberIII(vector<int> &A) {
        // write your code here
        int a_xor_b = 0;
        int a = 0;
        int b = 0;
        
        //Get xor result of the two single numbers. 
        //The bit which is 1 indicates at that bit A and B are different
        //The bit which is 0 indicates at that bit A and B are the same
        for (int &i : A){
            a_xor_b ^= i;
        }
        
        
        /***
         *  a_xor_b - 1: From the rightest(last) bit
         *               1) if the bit is 1, set that bit to 0, and keep the rest unchange and exit. 
         *               2) if the bit is 0, set that bit to 1, and check previous bit until 1)
         * ~(a_xor_b -1): The changed bit will be changed back, unchanged bit will be changed to opposite. 
         * a_xor_b & ~(a_xor_b -1): 1) unchanged bit will all be set to 0 (now they are different)
         *                          2) changed bit will be kept as original. 
         * The result of this opperation will provide us a number, 
         * which from the right(last), the first 1 will be kept and rest of bits will be set to 0,
         * comparing with a_xor_b;
         * eg. a_xor_b = 3(0011), (a_xor_b-1) = 2(0010), ~(a_xor_b-1) = (1101), a_xor_b & ~(a_xor_b -1) = (0001)
         *     a_xor_b = 5(0101), (a_xor_b-1) = 4(0100), ~(a_xor_b-1) = (1011), a_xor_b & ~(a_xor_b -1) = (0001)
         *     a_xor_b = 4(0100), (a_xor_b-1) = 3(0011), ~(a_xor_b-1) = (1100), a_xor_b & ~(a_xor_b -1) = (0100)
         *     a_xor_b = 6(0110), (a_xor_b-1) = 5(0101), ~(a_xor_b-1) = (1010), a_xor_b & ~(a_xor_b -1) = (0010)
         ***/
        int first_different_bit_from_right = a_xor_b & ~(a_xor_b - 1);
        
        /***
         * Second way:
         * // Get the last bit where 1 occurs. 
         * int first_different_bit_from_right = x_xor_y & -x_xor_y;
         * -x = ~x+1. Similar reason. 
         ***/
        
        
        //Divided the whole array to two groups,
        //The first group contains the numver which at particular bit, the bit value is 1;
        //The particular bit is the bit which is the rightest bit that a and b are different.
        //The second group contains number which at the particular bit, the bit value is 0;
        //Since at that bit, a and b are different,a and b must assign to different group.
        //The rest member of each group is even(same number will be sign to same group). 
        //If we XOR each group, the result will be the leftover one single number in each group
        
        for(int &i : A){
            if (i & first_different_bit_from_right ){
                a ^= i;
            } else {
                b ^= i;
            }
        }
        
        return {a, b};
        
        
    }
};

posted on 2020-04-24 02:11  codingEskimo  阅读(73)  评论(0编辑  收藏  举报

导航