Leetcode 600 Non-negative Integers without Consecutive Ones

来源:互联网 发布:芭蕾练功服推荐 知乎 编辑:程序博客网 时间:2024/06/05 03:22

leetcode 600

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: 5Output: 5Explanation: Here are the non-negative integers <= 5 with their corresponding binary representations:0 : 01 : 12 : 103 : 114 : 1005 : 101

Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.
Note: 1 <= n <= 109
在小于等于n的数中,找到所有满足相邻的bit位不同时为1的数.


这个可以对数字的最高位进行讨论:假设n的最高位在K
1. 找最高位也是K的无”11”数
2. 找最高位小于K的无”11”数

两部分加起来就是我们要的结果.


就最高位小于K的时候, 这个就比较好算了. 因为这些数一定是小于n的.
记最高位1 为 i 的无”11”数有 a[i] 种,

101xxx1001xx10001x100001100000

a[i] = a[i-2]+a[i-3] + … + a[0]

可进一步推得a[i] = a[i-1]+a[i-2].


对于最高位为K的数就比较麻烦了, 因为有小于等于n的限制在这.
遍历n的bit位, 从高到低. 如果遇到一个bit为1, 我们就把这位设为0, 剩下低位的部分就可以用上面a[i]来填补了.

10010011000xxx     剩下的这3个bitsa[3], a[2], a[1],a[0]对应的那些数来填补就可以了.

a还有一种特殊情况: n中包含”11”. 这样n这个数就不能算进去了. 而且在遇到最高的”11”的时候, 我们需要把它变为”10”, 或”01”.

1011010101100xxxxxxx 剩下的7位用a[7],a[6], ..a[0]对应的数填补1010xxxxxx 剩下的6位用a[6],a[5], ... a[0]对应的数来填补

为了计算方便, 我们可以先计算sum[i] = a[i] + a[i-1] + … + a[0]

class Solution {public:    /**      * @brief 找到二进制中最高位的"11"     *      * @param num     *      * @return 返回最高位"11"所在的位置     */    int find_dual1(const int num) {        int mask = (1<<1) + 1 ;        int b = -1;        for(int i = 1; i <= 30; ++i) {            if((num&mask) == mask){                b = i;            }            mask <<=1;        }        return b;    }    int find_int(const int num, const int b, const vector<int> & sum) {        int cnt = 0;        /*最高位等于b的数*/        int dual1_pos = find_dual1(num);        if(-1 == dual1_pos) {            cnt += 1;/*num self.*/        }        int next_b = b-1;        for(; next_b > dual1_pos; --next_b) {            if(num & (1 << next_b)) {                cnt += sum[next_b];            }        }        if(-1 != dual1_pos){            if(dual1_pos == b) {                cnt += sum[dual1_pos-1];            }else {                cnt += sum[dual1_pos];                cnt += sum[dual1_pos-1];            }        }        /*最高位小于b的数*/        cnt += sum[b];        return cnt;    }    int findIntegers(int num) {        int b = 0;         while(1<<(b+1) <= num) {            ++b;        }        vector<int> a(b+1, 0);        a[0] = 1;        a[1] = 1;        a[2] = 1;        for(int i = 3; i <= b; ++i) {            a[i] = a[i-1] + a[i-2];        }        vector<int> sum(b+1,0);        int s = 0;        for(int i = 0; i <= b; ++i) {            s += a[i];            sum[i] = s;        }        return find_int(num, b, sum);    }};
阅读全文
0 0
原创粉丝点击