您的位置:首页 > 其它

476. Number Complement

2017-10-15 16:29 441 查看
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.

看到complement第一反应是求数的补码(2’complement),即为二进制按位取反之后加1,然而看例子和具体描述,这道题应该求的是反码(1’complement),即仅二进制按位取反即可,不要弄错概念。

这道题的内容十分简单,就是已知一个十进制数,求出它的反码(十进制表示)。最简单的方法就是先将这个十进制数分解成二进制数,之后按位取反再乘以2的对应次方再相加,直接求出它的反码。使用数组或者是栈储存二进制数的每一位都可以。

参考代码如下:

class Solution {
public:
int findComplement(int num) {
stack<int> s;
int complement = 0;
while(num != 0) {
s.push(num % 2);
num /= 2;
}
int count = s.size();
for(int i = count - 1; !s.empty(); i--) {
complement += (1 - s.top()) * pow(2, i);
s.pop();
}
return complement;
}
};


当然,我们还有更巧妙的方法。在计算机当中,任何十进制数其实都是按二进制来存放的,我们完全可以想到“~”运算符——按位取反。但同时我们会遇到一个问题,~运算符是对每一位都按位取反。假设我们输入的是5,它的二进制数是101,在计算机中的表示是000…101,101的前面一共有29个0。也就是说,当我们使用~运算符进行按位取反操作,前面的29个0也会被取反变成了1,~5 = (111…010)2,这就变成不是我们所想要的结果,我们需要提取出我们需要的后3位,让前面置零。

我选择的方法是使用移位,在一开始记录下我们需要的位数,记为有效位数(count),然后通过先左移(32-有效位数)位,再右移相同位数,自动系统补零从而得到我们想要的结果。

参考代码如下:

class Solution {
public:
int findComplement(int num) {
int length = 0;
int temp = num;
while(temp != 0) {
length++;
temp >>= 1;
}
num = ~num;
num <<= (32 - length);
num >>= (32 - length);
return num;
}
};


另外膜拜一下discuss里面巨佬的思路,十分巧妙的使用了取反、按位与操作仅用3行边完成了这道题。首先通过mask=~0使mask全为1,之后利用while(mask&num) mask <<=1 使得mask变成111…100…000的形式,其中0的位数与num的二进制位数相同,也就是提取出了有效位数,之后利用~mask & ~num将~num中我们需要的位数提取出来,从而获得答案。真的是一个很巧妙的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: