持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
题目
对整数的二进制表示取反(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,再将这个 1 以及更低的位进行取反。
如果 二进制表示最高位的 1 是第 位,那么一定有:
因此我们可以使用一次遍历,在 中找出 的值。
在这之后,我们就可以遍历 的第 个二进制位,将它们依次进行取反。我们也可以用更高效的方式,构造掩码 ,它是一个 位的二进制数,并且每一位都是 。我们将 与 进行异或运算,即可得到答案。
细节
当 时,构造 的过程中需要保证不会产生整数溢出。下面部分语言的代码中对该情况进行了特殊判断。
代码
class Solution {
func findComplement(_ num: Int) -> Int {
var highbit: Int = 0
for i in 1...30 {
if num >= 1 << i {
highbit = i
}
else {
break
}
}
let mask: Int = highbit == 30 ? 0x7fffffff : (1 << (highbit + 1)) - 1
return num ^ mask
}
}
复杂度分析
-
时间复杂度:。找出 二进制表示最高位的 需要的时间为 。
-
空间复杂度:。