👉 “Offer 驾到,掘友接招!我正在参与2022春招打卡活动点击查看 活动详情。
600. 不含连续1的非负整数
题目描述
给定一个正整数 n ,返回范围在 [0, n] 都非负整数中,其二进制表示不包含 连续的 1 的个数。
示例 1:
输入: n = 5
输出: 5
解释:
下面是带有相应二进制表示的非负整数<= 5:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
其中,只有整数3违反规则(有两个连续的1),其他5个满足规则。
示例 2:
输入: n = 1
输出: 2
示例 3:
输入: n = 2
输出: 3
提示:
1 <= n <= 109
解题思路:
对于,例如100000,不符合条件的有三类,数量表示为f(n)
110000 - 11xxxx,共 个- 小于
010000的,即 - 大于
100000小于101000的,即 综上所述
后面的循环实际上相当于每次判断最高两位,跳过前置0
计算出不符合条件的数的数量 后,即可得符合条件得数得数量 ,因为包含0
代码如下:
class Solution:
def findIntegers(self, n: int) -> int:
if n < 6:
return n - (n+1) // 4 + 1
dp = {1: 0, 2: 0}
nn = 2
while nn < n:
nn <<= 1
dp[nn] = dp[nn >> 1] + dp[nn >> 2] + (nn >> 2)
if n == nn:
return nn - dp[nn] + 1
ans = n + 1
while True:
while nn > n:
nn >>= 1
if n == nn:
ans -= dp[nn]
break
if n >= nn * 3 // 2:
nn <<= 1
ans -= dp[nn] - nn + n + 1
break
else:
ans -= dp[nn]
n -= nn
return ans
- 时间复杂度
- 空间复杂度