476. Number Complement

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中我们需要的位数提取出来,从而获得答案。真的是一个很巧妙的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值