[LeetCode] 476.Number Complement 備忘
阿新 • • 發佈:2019-02-11
476. Number Complement
Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.
Note:
- The given integer is guaranteed to fit within the range of a 32-bit signed integer.
- You could assume no leading zero bit in the integer’s binary representation.
Example 1:
Input: 5 Output: 2 Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.
Example 2:
Input: 1 Output: 0 Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.
求一個數字的補數,即除了高位的0,所有位上面的值相反的數字。
最容易想到的方法就是如何得到一個mask,讓這個數的前面的幾位高位全是0,後面的低位都是1,這樣直接按位取反這個數之後和這個mask做一次位與操作就可以得到正確的結果了。所以首先讓mask為0xffffffff(題目中有32位長度的限制),之後以mask & 這個數不為0為迴圈條件,將mask一次一次的左移一位,這樣就將這個數右邊所有的位都成為0,將mask按位取反之後,得到之前我們所需要的那個mask,這樣即可求得這個數的補數。
還有一個巧妙的方法,以2為底計算這個數的對數,轉換為整型。以該值將1向左位移,然後減去1,作為mask。與這個數按位取反之後做位與操作得到結果。對於這個方法我的理解是,比如5的二進位制為101,log2(5)的結果轉換為整型是2,1左移2位,即為4,減去1為3,3的二進位制為11,以該值作為mask可以得到正確的結果。同理我們發現6和7,二進位制分別為110和111遵循相同的規律,即處於2^2和2^3之間,就是處於二進位制1000和100之間,這些數字二進位制的開頭永遠是第三位上的1,所以如果我們可以得到第二位置和第一位的值都是1的mask,就可以輕鬆算出這些數字的補數,同理其他的數字也是如此。class Solution { public: int findComplement(int num) { int mask = ~0; while (num & mask) { mask <<= 1; } return ~mask & ~num; } };
class Solution {
public:
int findComplement(int num) {
return ~num & ((1 <<(int)log2(num))-1);
}
};