1. 程式人生 > >137. 只出現一次的數字 II

137. 只出現一次的數字 II

clas 進制 數字 bsp 代碼 for turn color style

題目

給定一個非空整數數組,除了某個元素只出現一次以外,其余每個元素均出現了三次。找出那個只出現了一次的元素。

說明:

你的算法應該具有線性時間復雜度。 你可以不使用額外空間來實現嗎?

示例 1:

輸入: [2,2,3,2]
輸出: 3

示例 2:

輸入: [0,1,0,1,0,1,99]
輸出: 99

思路

計算二進制下,各個位上1的個數。

因為只有一個數出現1次,其他都出現3次,所以各個位上1的個數%3就是只出現1次的數的二進制表示。

  比如[2,2,4,2],二進制就是[0010,0010,0100,0010],那麽二進制對應位上1的個數位0 1 3 0,然後%3位0 1 0 0。也就是只出現1次的4。

因為%3那麽1的個數可能為0,1,2。用2位二進制表示即可。

  比如a=0010,b=0001(a高位,b低位)表示各個位上1的個數:0 0 2 1 [00 00 10 01]。

假設下一個數為c,可以知道:1、c的二進制位上為1時,b對應位肯定會發生變化。2、只有b對應位上由1變為0時,a對應位才會發生變化。3、當某個位上1的個數為3時,即a、b對應位都為1,置為0.

那麽1、只要c對應位是1,b對應位就變化:t=b^c;2、b對應位由1變為0時,a變化:a=c&b^a;(b更新:b=t;)3、當a、b對應位都為1時,置為0:temp=a;a=a^a&b;b=b^temp&b;(&優先級>^)

因為最後的結果表示的是一個數的二進制,那麽對應位的1的個數只可能是1或0,那麽低位的b就是最終的結果。

代碼

public static int singleNumber(int[] nums) {
        int a=0;
        int b=0;
        for(int i=0;i<nums.length;++i){
            int t=b^nums[i];
            a=nums[i]&b^a;
            b=t;
            int c=a;
            a=a^a&b;
            b=b^c&b;
        }
        return b;
    }



137. 只出現一次的數字 II