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.正常人看到这道题目的第一瞬间也应该知道是使用位运算。
开始的时候,我的想法是将整个整形数的最后有效部分取反。
但由于对位运算的计算不熟悉,所以才有了如下第一版的原始模式的代码。
public int findComplement(int num) {
int b1 = 0x80000000;
int lead = 0;
int res = 0;
for(int i=0;i<32;i++){
if(((num&b1)==0)&&lead==0){
b1=b1>>>1;
}else{
lead++;
res=res*2+((num&b1)==0?1:0);
// System.out.println(Integer.toBinaryString(res)+" "+Integer.toBinaryString(num&b1));
b1=b1>>>1;
}
}
return res;
}
回过头来看,这段代码对整形数的每一位都会重新计算,是很麻烦、原始的计算方法。
回顾了位操作的几个操作符后,就有了新的想法。
1.首先对整形数num按位取反,~num。这个操作后,我们需要判断有效位的个数。
2.采用Integer.highestOneBit(num) 方法找出最高位。
这个函数的作用是取num这个数的二进制形式最左边的最高一位且高位后面全部补零,最后返回int型的结果。
3.左移后-1,这样有效位全部被赋予1。
4.与~num进行位与操作。
return ~num & ((Integer.highestOneBit(num) << 1) - 1);
只需要一行。
在leetcode的最佳JAVA solution中,作者还说明,由于有效位的最高位的相反值一定是0,所以左移一位没有必要。
最优化结果为:
return ~num & (Integer.highestOneBit(num) - 1);