Leetcode——不含连续1的非负整数(数位DP,打家劫舍,理解不够深)

Posted Yawn,

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode——不含连续1的非负整数(数位DP,打家劫舍,理解不够深)相关的知识,希望对你有一定的参考价值。

1. 不含连续1的非负整数

(1)暴力

从1开始,按位增。如果当前结尾是1的话就补0;
如果是0的话就补0或者1;
如果大于n就停止。

class Solution {
    public int findIntegers(int n) {
        //0也是符合条件的,要加上1
        return 1 + dfs(1, n);  
    }
    
    public int dfs(int i, int n) {
        return i > n ? 0 : 1 + dfs(i << 1, n) + ((i & 1) == 1 ? 0 : dfs((i << 1) + 1, n));
    }
}

(2)递归(参考打家劫舍)

这道题其实有点类似 打家劫舍: 不能包含相邻的1

class Solution {
    HashMap<Integer, Integer> dp = new HashMap<>();

    public int findIntegers(int n) {
        // 特殊情况:0,1,10,11,100
        if(n < 4)
            return n < 3 ? n + 1 : n;

        // 是否已存储该情况
        if(dp.containsKey(n))
            return dp.get(n);

        int b = bits(n);
        // 第一位取0的个数
        int res = findIntegers((1 << b) - 1);
        // 根据第二位是不是1判断第一位取1的个数
        res += ((n >> (b - 1)) & 1) == 1? findIntegers((1 << (b-1)) - 1) : findIntegers(n - (1 << b));
        dp.put(n, res);
        return res;
    }

    public int bits(int n){
        for(int i = 31; i > 0; i--)
            if(((n >> i) & 1) == 1)
                return i;
        return 0;
    }
}   

以上是关于Leetcode——不含连续1的非负整数(数位DP,打家劫舍,理解不够深)的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 600 不含连续1的非负整数

不连续1的非负整数--我只会无脑的数位dp

LeetCode 600 不含连续1的非负整数[字典数 动态规划] HERODING的LeetCode之路

2022-02-21:不含连续1的非负整数。 给定一个正整数 n ,返回范围在 [0, n] 都非负整数中,其二进制表示不包含 连续的 1 的个数。 输入: n = 5 输出: 5 解释: 下面是带

Leetcode 600.不包含连续1的非负整数

动态规划-数位dp-233. 数字 1 的个数