位元運算總結

來源:互聯網
上載者:User

標籤:位元運算   面試   

情形一:數組中所有數都出現兩次,只有一個數出現一次


情形二:數組中所有數都出現兩次,只有兩個數出現一次

情形一二很多地方都有說明,這裡就不囉嗦了,有一點需要注意:當知道未經處理資料時,可以使用解方程的方法,這樣可以把上面的情形無線推廣,具體見編程之美


情形三:數組中所有數都出現三次,只有一個數出現一次

方法一:如果數組中的元素都是三個三個出現的,那麼從二進位表示的角度,每個位上的1加起來,應該可以整除3。如果有一個數x只出現一次,會是什麼情況呢?

如果某個特定位上的1加起來,可以被3整除,說明對應x的那位是0,因為如果是1,不可能被3整除如果某個特定位上的1加起來,不可以被3整除,說明對應x的那位是1

根據上面的描述,我們可以開闢一個大小為32的數組,第0個元素表示,A中所有元素的二進位表示的最低位的和,依次類推。最後,再轉換為十進位數即可。這裡要說明的是,用一個大小為32的整數數組表示,同樣空間是O(1)的。

int FindNumber(int a[], int n)  {  int bits[32];  int i, j;  // 累加數組中所有數位二進位位  memset(bits, 0, 32 * sizeof(int));  for (i = 0; i < n; i++) {for (j = 0; j < 32; j++)  {bits[j] += ((a[i] >> j) & 1);   }}int result = 0;  for (j = 0; j < 32; j++) {if (bits[j] % 3 != 0) result += (1 << j);  }return result;  } 
方法二:參考這裡

Single Number的本質,就是用一個數記錄每個bit出現的次數,如果一個bit出現兩次就歸0,這種運算採用二進位底下的位操作^是很自然的。Single Number II中,如果能定義三進位底下的某種位操作,也可以達到相同的效果,但是這個東西沒有現成的可用。
我們換個思路,Single Number II中想要記錄每個bit出現的次數,一個數搞不定就加兩個數,用ones來記錄只出現過一次的bits,用twos來記錄只出現過兩次的bits,ones&twos實際上就記錄了出現過三次的bits,這時候我們來類比進行出現3次就抵消為0的操作,抹去ones和twos中都為1的bits。

int singleNumber(vector<int>& data){int ones = 0,twos = 0,threes = 0,length = data.size(),i;for (i = 0;i < length;i++){twos |= ones & data[i];//記錄只出現過2次的bits,要在更新ones前面更新twosones ^= data[i];//記錄只出現過1次的bitsthrees = ones & twos;//ones和twos中都為1即出現了3次ones &= ~threes;//抹去出現了3次的bits,相當於模3運算twos &= ~threes;}return ones;//返回只出現一次的}

情形四:數組中所有數都出現三次,只有一個數出現兩次

按照情形三的方法二,只要返回twos即可,原理是一樣的

位元運算總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.