600. 不含连续1的非负整数
方法一:递归
自然数 n 转换为二进制数字,如: 和
所有 的数,考虑第二位,要么是1,要么是0。
对于 m:第二位是 0
前两位取 10 递归 $6 = (110)_2$,即除去前两位后的剩余二进制位;
第一位取 0 递归 $15 = (1111)_2$
对于 n:第二位是 1
前两位是 11 递归 $7 = (111)_2$,即除去前两位后的最大值,因为第二位只能取 0;
第一位取 0 递归 $15 = (1111)_2$
class Solution:
@lru_cache(None)
def findIntegers(self, n: int) -> int:
if n <= 3:
return n + 1 if n < 3 else n
bits = len(bin(n)) - 2
return self.findIntegers((1<<(bits-1))-1) + (self.findIntegers((1<<(bits-2))-1) if (n >> (bits - 2)) & 1 else self.findIntegers(n - (1<<(bits-1))))
# bin((1<<(5-1))-1) = '0b1111'
方法二:
class Solution:
def findIntegers(self, n: int) -> int:
dp = [0] * 32
dp[0] = 1
dp[1] = 2
dp[2] = 3
for i in range(3, 32):
dp[i] = dp[i - 1] + dp[i - 2]
numStr = str(bin(n))[2:]
m = len(numStr)
res = 0
for i in range(m):
if numStr[i] != '0':
res += dp[m - i - 1]
if i != 0 and numStr[i - 1] == '1':
return res
return res + 1