参考自:https://blog.youkuaiyun.com/midnight_time/article/details/79796968
给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。
注意:
- 给定的整数保证在32位带符号整数的范围内。
- 你可以假定二进制数不包含前导零位。
示例 1:
输入: 5
输出: 2
解释: 5的二进制表示为101(没有前导零位),其补数为010。所以你需要输出2。
示例 2:
输入: 1
输出: 0
解释: 1的二进制表示为1(没有前导零位),其补数为0。所以你需要输出0。
答案是:
class Solution {
public int findComplement(int num) {
return (~num) & (Integer.highestOneBit(num) - 1);
//或 return (~num) & ((Integer.highestOneBit(num)<<1) - 1);
}
}
完全看不懂。
|
分析,经过1) 首先定义一个 int 型的num,在计算机中占2字节,1字节 = 8 位 ,也就是说, 5 在计算机中存储的方式是: 00000000 00000101 ,
Integer.highestOneBit(5):取5的不含前导位的二进制的最高位,即101 取1,其他位都补0;得到100;
2)100 减一之后变为 011 ,这时再和 ~num 进行与运算, 因为011 位数不够,所以需要填补0,即 00000000 00000011
3)~num 的意思就是取反,即得到 11111111 11111010 ;
4)运算:~num: 11111111 11111010
& 00000000 00000011
得 00000000 00000010 即十进制的 2
参考的文档写的很详细且风趣/
总结:很直白的一个思路就是 把整型数字转换为二进制形式,再将二进制数取反,但是要考虑到32位的二进制数除了将int目标数转换为二进制的低位 的左边的高位数上的0,因为这些0不能取反 不能作为结果计算进去;