力扣每日一题2024.8.5

600.不含连续1的非负整数(困难)

给定一个正整数 n ,请你统计在 [0, n] 范围的非负整数中,有多少个整数的二进制表示中不存在 连续的 1
示例 1:

输入: n = 5

输出: 5

解释:

下面列出范围在 [0, 5] 的非负整数与其对应的二进制表示:

0 : 0

1 : 1

2 : 10

3 : 11

4 : 100

5 : 101

其中,只有整数 3 违反规则(有两个连续的 1 ),其他 5 个满足规则。
示例 2:

输入: n = 1

输出: 2
示例 3:

输入: n = 2

输出: 3

提示:

1 <= n <= 109

思路:

刚开始便是想到了暴力破解,但是想想这是困难题,看了看数据范围果然不简单。之后只能考虑用数位dp的方法进行解决。具体思路便是:

  1. 将输入的整数 n 转换为二进制字符串 binary
  2. 初始化两个数组 a[]b[],长度为二进制字符串长度 length,并且初始化 a[0] = 1b[0] = 1
  3. 循环处理每一位,根据动态规划的状态转移方程计算 a[]b[] 数组的值:
    • 对于 a[i],如果当前位是 0,则 a[i] = a[i-1] + b[i-1]
    • 对于 b[i],如果当前位是 1,则 b[i] = a[i-1]
  4. 计算最终结果 result = a[length - 1] + b[length - 1],这是在整个二进制数范围内满足条件的非负整数的个数。
  5. 再次遍历二进制字符串,检查是否有连续的1,如果有连续的0(也就是连续的0不符合条件),则通过减去 b[length - i - 1] 的方式来调整最终结果。
  6. 返回最终计算得到的结果 result,即在给定范围内满足条件的非负整数的个数。

总体来说,该代码使用动态规划来解决问题,通过预先计算满足条件的非负整数个数并且在遍历二进制字符串时进行调整,最终得到在给定范围内满足条件的非负整数个数。

java 复制代码
class Solution {
    public int findIntegers(int n) {
    String binary = Integer.toBinaryString(n); // 将 n 转换为二进制字符串 
    int length = binary.length();
    
    int[] a = new int[length];  // 表示在第 i 位为0时不包含连续1的数量
    int[] b = new int[length];  // 表示在第 i 位为1时不包含连续1的数量
    
    a[0] = 1;
    b[0] = 1;
    
    for (int i = 1; i < length; i++) {
        a[i] = a[i-1] + b[i-1];//计算在第 i 位为0时不包含连续1的数量,根据动态规划的规则,
        //当前位置为0时的数量等于上一位0和上一位1的数量之和。
        b[i] = a[i-1];//计算在第 i 位为1时不包含连续1的数量,当前位置为1时的数量等于上一位0时的数量。
    }
    
    int result = a[length - 1] + b[length - 1];//计算初始结果,即所有位数的情况下的满足条件的整数数量。
    
    for (int i = 1; i < length; i++) {
        if (binary.charAt(i) == '1' && binary.charAt(i - 1) == '1') {//如果当前位和前一位都是1,
        //则存在连续的1,跳出循环。
            break;
        }
        if (binary.charAt(i) == '0' && binary.charAt(i - 1) == '0') {
            result -= b[length - i - 1];
            //如果当前位和前一位都是0,则需要减去在这种情况下的数量,因为这样的情况不满足条件。
        }
    }
    
    return result;    
    }
}
相关推荐
零小陈上(shouhou6668889)5 分钟前
K-近邻算法 - lazy learning的代表
算法·近邻算法
有一个好名字11 分钟前
力扣-从字符串中移除星号
java·算法·leetcode
萧瑟其中~15 分钟前
二分算法模版——基础二分查找,左边界查找与右边界查找(Leetcode的二分查找、在排序数组中查找元素的第一个位置和最后一个位置)
数据结构·算法·leetcode
码上就好ovo17 分钟前
Atcoder Beginnner Contest 440
算法
高洁0124 分钟前
CLIP 的双编码器架构是如何优化图文关联的?(3)
深度学习·算法·机器学习·transformer·知识图谱
jllllyuz30 分钟前
MATLAB实现蜻蜓优化算法
开发语言·算法·matlab
AlenTech31 分钟前
208. 实现 Trie (前缀树) - 力扣(LeetCode)
leetcode
iAkuya32 分钟前
(leetcode)力扣100 36二叉树的中序遍历(迭代递归)
算法·leetcode·职场和发展
wangwangmoon_light40 分钟前
1.1 LeetCode总结(线性表)_枚举技巧
算法·leetcode·哈希算法