LeetCode题解 week6

来源:互联网 发布:c语言宏定义 编辑:程序博客网 时间:2024/06/04 18:29

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

原创粉丝点击