40.乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。
陣列裡包含了兩個只出現一次的數字,那麼所有數字依次異或的結果就是這兩個只出現一次的數字的異或結果。我們要想辦法利用這個異或結果,把陣列分為兩個子陣列,乙個子陣列包含乙個只出現一次的數字,另乙個陣列包含另乙個只出現一次的數字。由於這兩個只出現一次的數字肯定不相等,那麼這個異或結果肯定不為0,也就是說在這個結果數字的二進位制表示中至少就有一位為1。我們在結果數字中找到第乙個為1的位的位置,記為第n位。現在我們以第n位是不是1為標準把原陣列中的數字分成兩個子陣列,第乙個子陣列中每個數字的第n位都為1,而第二個子陣列的每個數字的第n位都為0。
舉個栗子:1 2 3 4 2 3
所有數字異或結果 = 1 xor 4
異或結果的二進位制位101,第乙個為1的位的位置n=1。
那麼,陣列所有數的二進位制表示中,第n(n=1)位為1的的數為1 3 3,第n(n=1)位為0的的數為2 2 4.
這樣就把原陣列拆分為兩個子陣列,1和4被分到不同的陣列中去了。然後分別在兩個子陣列中找只出現一次的那個數。
異或運算遵循交換分配率:
如果我們從頭到尾依次異或陣列中的每乙個數,那麼最終的結果就是那個只出現一次的數字,
因為其他出現兩次的數字全部在異或中被抵消為0了(異或運算遵循交換分配率)。
舉個栗子:234
23所有數字依次異或運算:2 xor 3 xor 4 xor 2 xor 3=(
2 xor 2
) xor (
3 xor 3
) xor 4
=0 xor 0 xor 4=4
最終結果4就是我們要找的那個只出現一次的數字。
public
class
solution
int result =0;
for(
int i=
0;i < array.length; i++
)int index =
find
(result)
;// num1 = num2= [0];
for(
int j=
0; j< array.length;j++
)else}}
public
intfind
(int result)
return index;
}public
boolean
is1(
int target,
int index)
}
劍指Offer(五) 位運算
寫乙個函式,求兩個整數之和,要求在函式體內不得使用 四則運算符號。位運算 coding utf 8 class solution def add self,num1,num2 write code here a,b num1,num2 while b 0 a,b a b,a b 1 a 0xffff...
劍指offer 學習筆記 位運算
位運算是把數字用二進位制表示後,對每一位上的0或者1的運算。面試題15 二進位制中1的個數。請實現乙個函式,輸入乙個整數,輸出該數二進位制表示 即補碼表示 中1的個數。例如,把9表示成二進位制是1001,有2位是1。因此,如果輸入9,則函式輸出2。很快我們得到乙個思路,先判斷該數二進位制表示中右邊一...
劍指offer刷題記錄 位運算
輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。由於數字在計算機中儲存的形式就是二進位制,因此可以直接將數字與1相與來判斷二進位制形式下最低位是否為1,然後右移數字繼續判斷直到數字為0即可。但是還要考慮負數形式,由於負數在儲存時,最高位有一符號位,在右移過程中最高位會不斷補1,所以...