刷题日记 476. 数字的补数

100 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情

一、题目描述:

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

对整数的二进制表示取反(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

二、思路分析:

这道题主要是用异或,任何一个数 异或相同位数二进制全1得补数
如 101^111=010 1100^1111=0011
关键在于确定二进制全1的位数 是三个1还是四个1还是n个1

如果有2的n次方大于num 2的n-1次方小于num 那么n-1就是要异或全1的位数
但是2的n-1次方二进制是10000...00 要得到相同位数的二进制全1只需要向左移一位后减一 即nx2-1或者n<<1-1
最后异或就能得到补数。
unsigned int n = 1;
while (n <=num) n*=2;
return (n-1)^ num;

三、AC 代码:

class Solution {
public:
    int findComplement(int num) {
        unsigned int n = 1;	/*防止数据溢出*/	
		while (n <=num)  n*=2; /*找到第一位 二进制1*/
		return (n-1)^ num; /*   (n/2*2-1)^num    */
    }
};

四、参考:

找到第一位1 后异或 - 数字的补数 - 力扣(LeetCode)

【仗剑骑士】C++, 两种方法迭代+lowbit, +476. 数字的补数 - 数字的补数 - 力扣(LeetCode)

【微扰理论】补数 = 取反并截掉最高位以上的1 - 数字的补数 - 力扣(LeetCode)