我的解法:
1.題意要素:
(1)正整數
(2)前驅的0不計入置反的操作,比如5的二進制值位00000101,那么其會被置反的只有‘101’這部分,前面的0都不算。
2.關鍵技巧:
和‘1’相與結合右移可以達到判斷某一位是否為0的目的,能夠知道哪個位是哪個值就能累加到最終結果。
3.具體解法:
聲明一個變量n記錄當前操作的位,作為累加的冪。將其逐位右移直到變為0,右移時還要n+1記錄當前操作的位數。每次右移前與1相與,如果結果是0,則代表該位源值為0,最終結果就需要累加2^n。
#include <iostream>#include <cmath>using namespace std;int findComplement(int num);int main(){ int num; cin >> num; cout << findComplement(num) << endl; return 0;}int findComplement(int num) { int cp = 0; int power = 0; if(!num){ return 1; } while(num != 0){ if((num & 1) == 0){ cp += pow(2, power); } power++; num = num >> 1; } return cp;}網上的另一種解法,覺得挺巧妙的,然而并沒有變快,也是3ms,出處:https://discuss.leetcode.com/topic/74897/maybe-fewest-Operations/2
int findComplement(int num) { int mask = num; mask |= mask >> 1; mask |= mask >> 2; mask |= mask >> 4; mask |= mask >> 8; mask |= mask >> 16; return num ^ mask;}大致思路就是:首先分析題意??蓪㈩}意總結為將給定數字和一個特定的掩碼進行XOR操作(異或操作)。這個掩碼和給定數有同樣的位數,且在其最高位右邊全部都是1。以5為例,其二進制表示為101,那5就有3位,那么5(101)對應的掩碼為111,5和掩碼111異或操作后就可以得到101,也就是題意要求的結果。另一個掩碼的例子是38(100110)的掩碼是111111。
這樣一來,問題就濃縮成了“如何獲取這個掩碼”。我們知道,不管是啥正整數,其最高位必定是1,我們可以將其最高位不斷右移,來填滿余下的低位,得到一個從最高位開始向右都為1的掩碼。先看下一個8位的數字,后面可以延伸到32位。以64(01000000)為例,我們的目的是將第6-1位置為1。一開始第7位是1,mask |= mask>>1 將第6位也置為1,這樣就得到了01100000。接下來是mask |= mask>>2 ,將5和4位置為1,得到011110000。這里移動2位,因為經過第一步我們已經將mask的高兩位置為1了,所以可以移動兩位來節省操作,當然你也可以逐位移動。 接下來以為高4位被置為1了,可以移動4位,得到01111111這樣就全部置為1了,當然你也可以移動1,2,4位,隨你喜歡。
32位如何移,可以看源碼自行理解。
原文如下:
@NoAnyLove To understand the solution, we need to go backwards. The aim is to xor the given number with a mask. The mask should contain all 1s in its rightmost bits. However, the number of rightmost bits is important. In the case of 5(101), for example, the number of rightmost bits must be 3, since 5 uses 3 rightmost bits. The mask must be 111 for 5(101). When we xor 111 with 101, we will get 010. As another example, the mask will be 111111 for 38(100110)So the PRoblem boils down to generating the mask. Let's think about 8-bit numbers. We can later extend the same logic to 32-bit integers. I will count the bits from right to left, starting with 1.The largest positive numbers represented by 8 bits will set 7th bit. 64(01000000) is the largest positive number represented by 8 bits, which has the most number of 0s. It is important for our explanation since we must turn all those 0s into 1s.The first operation, mask |= mask>>1; will set the 6th bit. So, mask will become (01100000). Now, we know that the 7th and 6th bits are set, we can safely shift the mask to right by not 1 but 2 bits. mask |= mask>>2; will now set the 5th and 4th bits. By the same reason, we can now shift the mask to right by not 1, 2 or 3 but 4 bits. That is the threshold for 8-bit numbers. We do not need to shift more.For 32-bit integers, the shift operations should continue until reaching to 16. For 64-bit longs, that will be 32.
新聞熱點
疑難解答
圖片精選