十进制整数的反码

标签: 位运算

难度: Easy

每个非负整数 N 都有其二进制表示。例如, 5 可以被表示为二进制 "101"11 可以用二进制 "1011" 表示,依此类推。注意,除 N = 0 外,任何二进制表示中都不含前导零。

二进制的反码表示是将每个 1 改为 0 且每个 0 变为 1。例如,二进制数 "101" 的二进制反码为 "010"

给你一个十进制数 N,请你返回其二进制表示的反码所对应的十进制整数。

示例 1:

输入:5
输出:2
解释:5 的二进制表示为 "101",其二进制反码为 "010",也就是十进制中的 2 。

示例 2:

输入:7
输出:0
解释:7 的二进制表示为 "111",其二进制反码为 "000",也就是十进制中的 0 。

示例 3:

输入:10
输出:5
解释:10 的二进制表示为 "1010",其二进制反码为 "0101",也就是十进制中的 5 。

提示:

  1. 0 <= N < 10^9
  2. 本题与 476:https://leetcode-cn.com/problems/number-complement/ 相同

Submission

运行时间: 18 ms

内存: 15.9 MB

class Solution:
    def bitwiseComplement(self, N: int) -> int:
        x=str(bin(N))[2:].replace('1','2').replace('0','1').replace('2','0')
        return int(x,2)

Explain

题解采用了直接操作字符串的方法来求解二进制的反码。首先,使用`bin(N)`函数将整数N转换为二进制字符串,然后去掉前缀'0b'。接着,通过替换操作将所有的'1'变为'2'(中间状态),将所有的'0'变为'1',最后将所有的'2'变为'0',从而完成了反码的生成。最后,使用`int(x, 2)`将得到的二进制字符串转换回十进制整数。

时间复杂度: O(b)

空间复杂度: O(b)

# 定义解题类
class Solution:
    def bitwiseComplement(self, N: int) -> int:
        # 将整数N转为二进制字符串,并去除前缀'0b'
        x = str(bin(N))[2:]
        # 首先将所有的'1'替换为'2'(避免直接替换成'0'导致与原有的'0'混淆)
        x = x.replace('1', '2')
        # 将所有的'0'替换为'1'
        x = x.replace('0', '1')
        # 最后将所有的'2'替换为'0'
        x = x.replace('2', '0')
        # 将二进制字符串转换为十进制整数
        return int(x, 2)

Explore

在进行替换操作时,首先将所有的'1'替换为'2'是为了避免替换冲突。如果直接将'1'替换为'0',那么在随后的步骤中,我们无法区分原始字符串中的'0'和被替换后的'0'。使用'2'作为中间状态可以帮助我们区分这些字符,从而正确地完成所有替换步骤。

当N为0时,二进制表示为'0'。按照算法,这将被替换为'1',然后直接转换回十进制,结果也是1。这种情况下算法依然有效并且不需要特别处理,因为在二进制中'0'的反码确实是'1'。

是的,存在更高效的方法来实现反码。一种方法是使用位运算。首先,可以通过位运算计算出与N长度相同的全1的二进制数,然后使用异或运算符(^)来直接获取反码。这种方法减少了字符串操作,只涉及几次位运算,因此在性能上更优。

如果输入的N非常大,该算法的性能可能会受到影响。由于算法涉及到字符串操作,包括创建二进制字符串、多次替换操作以及最后的字符串到整数的转换,这些操作的时间复杂度和空间复杂度都随着N的增大而变得不那么高效。尤其是字符串替换操作,它在处理很长的字符串时可能成为性能瓶颈。使用位运算可以显著提高处理大整数的效率。