1. 程式人生 > >lintcode83- Single Number II- midium

lintcode83- Single Number II- midium

特征 except find class n+2 urn 出現一次 情況 write

Given 3*n + 1 numbers, every numbers occurs triple times except one, find it. Given [1,1,2,3,3,3,2,2,4,1] return 4 法1:加和掩碼提取位,模三,加到結果裏。int 數據共有32位,針對其中具體某一位,可以用掩碼(>>操作和 &1操作)把所有數字的這一位都加起來。針對重復3次的數字,他們加的和%3必定為0(0*3 %3 ==0, 1*3 %3 ==0),那麽所有的和%3得到的必定就是尋找的數在這一位上到底是1還是0了。把這一位<<,並且加到res變量返回即可。
public
class Solution { /** * @param A : An integer array * @return : An integer */ public int singleNumberII(int[] A) { // write your code here int res = 0; for (int i = 0; i < 32; i++){ int rsBit = 0; for (int idx = 0; idx < A.length; idx++){
int bit = A[idx] >> i; bit &= 1; rsBit += bit; } rsBit %= 3; res += rsBit << i; } return res; } }

法2:利用三個變量分別保存各個二進制位上 1 出現一次、兩次、三次的分布情況,最後只需返回變量一。 1. 代碼使得這三個變量表現形式是: 某數第一次出現- 100,某數第二次出現-010,某數第三次出現- 111(後續抹去變為001)。所以如果某個數是只出現一次(3n+1),它的特征位會被保留在ones中,如果某個數是出現正好兩次(3n+2),它的特征位會被保留在twos中。 2. 小心一下循環裏要先處理2再處理1。 3. |= 是想做賦一處理,&= 是想做歸零處理。^= 是想做“突出奇數次特征位,抹平偶數次特征位”處理。
public
class Solution { /** * @param A : An integer array * @return : An integer */ public int singleNumberII(int[] A) { // write your code here int ones = 0, twos = 0, threes = 0; for(int i = 0; i < A.length; i++){ //某數第一次進來,ones twos threes 1 0 0 //某數第二次進來,ones twos threes 0 1 0 //某數第三次進來,ones twos threes先1 1 1, 後 0 0 1 //某數第四次進來,ones twos threes 1 0 0 //循環 twos |= ones & A[i]; ones ^= A[i]; threes = ones & twos; //第三次來時抹去一二痕跡 twos &= ~three; ones &= ~three; } return ones; } }

lintcode83- Single Number II- midium