算法笔记 -- 476. 数字的补数

111 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

一、题目描述:

476. 数字的补数 - 力扣(LeetCode)

对整数的二进制表示取反(0 变 1 ,1 变 0)后,再转换为十进制表示,可以得到这个整数的补数。

例如,整数 5 的二进制表示是 "101" ,取反后得到 "010" ,再转回十进制表示得到补数 2 。 给你一个整数 num ,输出它的补数。

示例 1:

输入:num = 5
输出:2
解释:5 的二进制表示为 101(没有前导零位),其补数为 010。所以你需要输出 2 。

示例 2:

输入:num = 1
输出:0
解释:1 的二进制表示为 1(没有前导零位),其补数为 0。所以你需要输出 0 。

提示:

  • 1 <= num < 2^31

二、思路分析:

计算机存储整数时,并不会仅仅存储有效的二进制位,采用32位整数存储时结果为(0000 0000 0000 0101)2 当num == 5 时;
要首先找到num二进制表示最高位的那个1,再将这个1以及更低的位进行取反。
找到num之后,构造掩码mask = 2^i+1 - 1, 它是一个i+ 1 位的二进制数,并且每一位都是1,我们将num与mask进行异或运算,即可得到答案

整个整数 0x7FFFFFFF 的二进制表示就是除了首位是 0,其余都是1
就是说,这是最大的整型数 int(因为第一位是符号位,0 表示他是正数)
用 INT_MAX 常量可以替代这个值。

三、AC 代码:

class Solution {
public:
    int findComplement(int num) {
        int highBit = 0;
        for(int i = 1; i <= 30; ++i){
            if(num >= (1 << i)) {  //1 << i表示将1左移i个位,相当于乘以2的i次方
                highBit = i;
            }
            else {
                break;
            }
        }
        int mask = (highBit == 30 ? 0x7fffffff : (1 << (highBit + 1)) - 1);
        return num ^ mask;
    }
};

四、参考:

【zljhero】【C语言】 数字的补数:利用栈保存二进制位,取反计算 - 数字的补数 - 力扣(LeetCode)

简单解法 - 数字的补数 - 力扣(LeetCode)