📅  最后修改于: 2023-12-03 15:23:29.487000             🧑  作者: Mango
在二进制表示法中,给定一个整数,找到一个比它大的整数,该整数的二进制表示法中不包含连续的1。
输入: 5 (101)
输出: 6 (110)
输入: 6 (110)
输出: 9 (1001)
一个朴素的想法是从给定的整数开始递增,直到找到一个整数,该整数的二进制表示法中不包含连续的1。这种方法的时间复杂度为 $O(2^n)$,其中 $n$ 是二进制表示法中 $1$ 的位数。
观察给定的整数的二进制表示法,我们会发现:如果末尾有一个 $0$,那么下一个较大的数就是将这个 $0$ 变成 $1$。如果末尾有一个 $1$,那么将它变成 $0$,并且将下一个 $0$ 变成 $1$。例如,对于 $10110$,下一个较大的数是 $11001$。
我们可以维护两个标记:$last$ 和 $current$,分别表示最近的一个 $0$ 和 $1$ 出现的位置。然后从最低位开始扫描,如果当前位是 $0$,那么将 $last$ 修改为当前位置;如果当前位是 $1$,那么将 $current$ 修改为当前位置。当遍历到一位时,我们检查当前位的值以及 $last$ 和 $current$,以决定下一个更大的数。
class Solution:
def findNextNumber(self, num: int) -> int:
# 将数字转换为二进制
bin_num = bin(num)[2:]
current, last = len(bin_num), len(bin_num)
for i in range(len(bin_num)-1, -1, -1):
if bin_num[i] == "0":
last = i
else:
if current == len(bin_num):
current = i
if last < current:
# 将最后一个0变为1,后面全部变为0
return int(bin_num[:last] + "1" + "0" * (current-last-1) + "1" + "0" * (len(bin_num)-current-1), 2)
last,current = current, i
# 无解
return -1
本文介绍了一个在二进制表示法中找到下一个没有连续1的更大元素的问题,并给出了两种解法。其中,暴力法的时间复杂度为 $O(2^n)$,而基于位运算的解法的时间复杂度为 $O(n)$。需要注意的是,在查找下一个较大的数时,必须确保新的数不大于 $2^{32}-1$。