題目:
請寫一個方法,找出int陣列中只出現過一次的數字,其他數字都會出現三次
舉例:
輸入{1,1,3,1}
的話,應該要輸出3
那在開始前不乏提醒一下此系列的固定提醒:
這是一系列逐漸帶入解題的文章,難度會隨著進度增加,若還沒有讀過前面的文章,建議先從最前面開始來逐漸練習解題喔!
這題是single number的續集,讓我們先列出一個邏輯吧!
(還沒有看過前面題目的話,建議先去看看喔)
讓我們先上程式碼再一一解釋:
class Solution {
public int singleNumber(int[] nums) {
int one=0, two=0;
for(int n : nums) {
one = (one^n) & ~two;
two = (two^n) & ~one;
}
return one;
}
}
除了one, two之外都是啥東西?!
讓我們逐一解釋一下流程
首先one, two的運作邏輯應該是這樣:
實際上流程是:
所以說,我們把{1,1,1}
丟進去的話,one和two的變化應該要是:
那大家一定會問& ~one
和& ~two
到底是幹嘛用的?
因為上面的程式碼一定會先把n丟進one及two內做XOR,所以後面的東西是「如果不應該把n丟進去XOR,就把前面的動作取消」
大家知道 1 & ~1 = 0 這件事對吧?(1和反1做AND會抵消)
& ~two
就代表說,如果n
已經在one內,而two中也有n
,n
就會被抵銷。因為two內的n
變成了~n
(反n)
& ~one
相同,如果n
已經在two內,而one中也有n
,n
就會被抵銷。因為one內的n
變成了~n
(反n)
大家可以試著在腦中想像{1,1,1}
丟進去這串程式碼後的運作過程,想像一下就會通了
這樣位元運算就結束嘍
明天開始我們來進入遞迴的題目