600. Non-negative Integers without Consecutive Ones
Given a positive integer n, find the number of non-negative integers less than or equal to n, whose binary representations do NOT contain consecutive ones.
Example 1:
Input: 5
Output: 5
Explanation:
Here are the non-negative integers <= 5 with their corresponding binary representations:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.
Note: 1 <= n <= 109
题目大意:
找到小于n 切2进制表示中没有连续的1的数的个数
思路:
这是一道动态规划的题目
我们用dp[n]来表示小于2^n的没有连续1的数的个数
假设n=5
则我们要找从000000到100000间所有满足条件的数,
1. 假设最高位为1 则次高位不能为1,从而问题变成要从10000到10111的所有满足条件的数的个数
2. 假设最高位为0 则次高位可以是1 ,从而问题变成从00000到011111的所有满足条件的数的个数
因此dp[5]=dp[3]+dp[4] 从此类推出dp[n]=dp[n-1]+dp[n-2];
是不是很眼熟,是的这就是fibonacci数列。
到此我们可以得到当n刚好是2的整数倍的时候满足条件的个数,当有连续两个出现的时候,将当前dp加到个数里面然后返回,因为后面的都肯定是非法的。
举例,
当我们需要求n=10111000的满足条件数的个数,
首先我们得到00000000-01111111的个数,之后就是111000的个数,当连续的1出现的时候就不需要在往下求了
class Solution {
public:
int findIntegers(int num) {
int f[32];
f[0] = 1;
f[1] = 2;
for (int i = 2; i < 32; ++i)
f[i] = f[i-1]+f[i-2];
int ans = 0, k = 30, pre_bit = 0;
while (k >= 0) {
if (num&(1<<k)) {
ans += f[k];
if (pre_bit) return ans;
pre_bit = 1;
}
else
pre_bit = 0;
--k;
}
return ans+1;
}
};