476. Number Complement【位运算】

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:

  1. The given integer is guaranteed to fit within the range of a 32-bit signed integer.
  2. 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);
    }
}

  

 
原文地址:https://www.cnblogs.com/flyfatty/p/6624792.html