2017/3/14 15:36:44
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.
解法1
思路:5的二进制 00000101 , 取反后 11111010 , 应该返回 00000010,从左至右遇到第一个0截止,切前面的1替换为0即为答案。
public class Solution {
public int findComplement(int num) {
num = ~num;
int flag = 31;
while( (1<<flag & num) != 0 ){
--flag;
}
int comparer = 1<<flag;
comparer |= comparer>>1;
comparer |= comparer>>2;
comparer |= comparer>>4;
comparer |= comparer>>8;
comparer |= comparer>>16;
return comparer & num ;
}
}
鉴于jdk中Integer类中有一个highestOneBit函数如下 ,作用 00010011---> 00010000 ,可以简化解法1的while循环
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
顺便,了解了源码中如何得到最后一个1,作用 00001100 --> 00000100 函数如下
public static int lowestOneBit(int i) {
// HD, Section 2-1
return i & -i;
}
另 00001000 --> 00001111 , 在只有一个1的情况下填充1 有个更简单的方法,num<<1 - 1 。因此可以简化解法1的5个或位运算,得到解法2。
解法2:(借鉴discuss)
public class Solution {
public int findComplement(int num) {
return ~num & ((Integer.highestOneBit(num) << 1) - 1);
}
}
又 因为 num取反后 11111010, 所以不需要 00000111,只需要00000011即可,因此不用左移1位,这是比较多余的一步。
public class Solution {
public int findComplement(int num) {
return ~num & (Integer.highestOneBit(num) - 1);
}
}