LeetCode 数字的补数

215 阅读1分钟

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

一、题目描述:

476. 数字的补数 - 力扣(LeetCode) 对整数的二进制表示取反(0110)后,再转换为十进制表示,可以得到这个整数的补数。

  • 例如,整数 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

二、思路分析:

不需要求出具体的2进制是多少。我们只需要求出输入数据转化为2进制有多少位即可
具体思想如下,我们来看个规律

  1. 输出数字是5的话,转换成2进制有3位
  2. 3位二进制的最大值为111,即十进制的7
  3. 补码 = 111 - 101 = 010 (其实就是 7 - 5 = 2 )
  4. 7怎么来的呢?7 = 8 - 1
  5. 8怎么来的呢?因为我们上面知道了5转换为二进制有3位,而2的3次方=8
  6. 所以,我们只需要知道一个信息就可以求出补码,而不需要具体求出5对应的2进制是多少,更不用二进制计算差值再转为十进制
  7. 这个信息就是:输出数据转化为二进制有多少位

有了思路再来撸代码就很方便了
1、利用递归的方法求出输入2进制有x位
2、计算x位二进制数的最大值(2的x次方 -1 )

三、AC 代码:

class Solution:
    def findComplement(self, num: int) -> int:
        if num == 0:
            return 1
        # 利用递归获取该10进制转化为二进制的位数
        def get_bin_nums(num):
            # 递归终止条件
            if num == 0:  # 如果余数为0,则直接返回0return 0
            if num == 1:  # 如果余数是1,则返回1return 1
            num = num // 2
            return get_bin_nums(num) + 1
        
        bin_nums = get_bin_nums(num) # 获取到位数之后,求出该位二进制对应的最大值(2的x次方-1)
        bin_max = 2 ** bin_nums - 1
        return bin_max - num  # 最后十进制的补码就是对应二进制的最大值减去输入的值