[Leetcode学习-java]Non-negative Integers without Consecutive Ones

问题:

难度:hard

说明:

给出一个整形,然后对整形修改为二进制形式,然后要求返回 [0, n] 所有二进制形式整形不存在连续两个 1 连在一起的数量。

题目连接:https://leetcode.com/problems/non-negative-integers-without-consecutive-ones/

输入范围:

  • 1 <= n <= 109

输入案例:

Example 1:
Input: n = 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. 

Example 2:
Input: n = 1
Output: 2

Example 3:
Input: n = 2
Output: 3

我的代码:

因为 10^9 这个数量很大,如果一个整型 32 个 位都遍历肯定会超时,不过好像可以用前缀,最后我试了下确实可以用前缀算法处理,先假设从 0 开始,每拼接一个新的 1 就相当于加入新的前缀元素:

1、先确定 0 的时候不重复 1 位数量是 1 , 1 的时候不重复 1 位数量是 1,这些代表 1 bit 的不重复总和是 2(0、1 只占 1 bit,而整形 31 位 其他所有位都是 0)

2、从 2 开始不断拼接新的 1 进入原来二进制中,那么以 1 开头的两位 bit 10,而如果 11 这样就是连续位不符合,就变成以 1 开头的 2 个 bit 最多不重复位总和是只有 10 ,1个。那么 1 开头 3 个 bit 就是 除了 2 个 bit 开头的位数总和(因为 100 开头遇到所有 110开头的都是重复,所以不算入总和),就变成以 1 开头的 3 bit 总和是 1 bit 总和 2,之间隔了一个 1。

3、2里面只算出了各个 1 开头前缀,然后还需要把所有前缀都相加,做一个前缀和,就能够求出 n bit 的以 1 开头的总和了。

4、最后就直接判断输入给出的位,从高往低判断,如果发现 11 两个连续的就代表高位 1 已经覆盖了所有数量,就直接返回,如果发现数字所有都没有重复,结果需要 + 1,因为少了 最高位 1开头后面都是 0 的统计。

Java:

class Solution {
    private static int[] pre = new int[32], total = new int[32];
    static {
        pre[0] = total[0] = 1;
        pre[1] = 1;
        total[1] = 2;
        for(int i = 2; i < 32; i ++) {
            pre[i] = total[i - 2];
            total[i] = pre[i] + total[i - 1];
        }
    }
    
    public int findIntegers(int n) {
        int res = 0;
        boolean duplicate = false;
        for(int i = 31, tmp = 1 << i; i >= 0; tmp = 1 << -- i)
            if((n & tmp) != 0) {
                res += total[i];
                if(duplicate) return res;
                duplicate = true;
            }
            else duplicate = false;
        return res + 1;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值