600. Non-negative Integers without Consecutive Ones

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值