LeetCode 600. Non-negative Integers without Consecutive Ones 题解
来源:互联网 发布:达达妈淘宝店卖假货吗 编辑:程序博客网 时间:2024/05/21 11:23
LeetCode 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 : 101Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.
Note:
题目分析
题目大意是求出0~n范围内, 有多少个数用二进制表示时不会出现连续的1
思路:
朴素思想是从0~n
逐一判断,看其是否违反约束。 对于判断的每一个数, 最多需要判断32位。可以近似看做判断一个数是否满足条件的复杂度 是
这题的数据范围
下面说更优的解法。数位DP。
数位DP之前有写过一道题, 所以大致的思想就不想再重复一遍了。直接说一下如何DP,以及状态转移方程。
首先,为什么这题可以用数位DP? 注意到这题的新状态显然是可以由先前的状态推导出来的。 并且可以由一系列在“位”层面的
先以普通的DP形式来举几个例子。转成数位DP并不复杂。
看看看转成以下形式是否也有问题:
前面若干项和应该不难理解。 之后的
更简洁的, 可以写成如下形式:
这样写的意思很明显, 后续全是0的都先不算, 最后再加上1即可。
这个例子和上面那个有所不同, 因为它的二进制本身就有连续
这个例子可以表示成如下形式:
对比可以发现, 这里有两处不同:
1. 出现连续
2. 最后不需要补上
对于第一点,考虑例子的最后几位
这里再多加解释一个小问题。 考虑如下例子:
按照上面所说, 分解为
但是考虑到分解成
对于第二点, 如果真的理解了为什么要补上后续为
好了解释就到上面了。 下面是实现代码。 代码大体上很好理解, 但是其中有若干个地方就体现了刚才说的几个需要注意的细节。
class Solution {public: vector<int> equalBitOnes(vector<int> v, bool & merge) { vector<int> ans; if (v.size() == 0) return ans; ans.push_back(v[0]); for (int i = 1; i < v.size(); ++i) { if (v[i] < ans[ans.size() - 1] - 1) ans.push_back(v[i]); else { if (v[i] == ans[ans.size() - 1] - 1 && ans[ans.size() - 1] - 1 >= 0) { ans.push_back(ans[ans.size() - 1] - 1); merge = true; return ans; } } } merge = false; return ans; } vector<int> getBitOnes(int n) { int i = 0; vector<int> ans; while (n > 0) { if (n & 0x1) ans.push_back(i); ++i; n >>= 1; } reverse(ans.begin(), ans.end()); return ans; } int findIntegers(int num) { bool merge = false; vector<int> bitOnes = equalBitOnes(getBitOnes(num), merge); vector<int> Fibo(max(bitOnes[0], 2) + 1, 0); Fibo[0] = 1; Fibo[1] = 2; for (int i = 2; i <= bitOnes[0]; ++i) { Fibo[i] = Fibo[i - 1] + Fibo[i - 2]; } int ans = 0; for (int i = 0; i < bitOnes.size(); ++i) { ans+= Fibo[bitOnes[i]]; } return (merge ? ans : ans + 1); }};
其他细节
- 通篇我并没有说分解到若干个
base=2k−1 后, 如何计算这些base 的函数值。 这并不是一个难解决的问题。 事实上就是一个Fibonacci 数列。 - 整体的思路其实并不难想, 但是细节的处理要十分小心。 20min想出思路, 却花了3个多小时来调细节。。。 归根到底还是对思路不够明晰, 在处理重复的时候犯了很多次错。
- 数位DP有明显的套路性(至少一些简单的数位DP是这样)。可以和之前我写的那篇对比。 真的是思出同门~.~
The End.
- LeetCode 600. Non-negative Integers without Consecutive Ones 题解
- 【LeetCode】600. Non-negative Integers without Consecutive Ones
- Leetcode 600. Non-negative Integers without Consecutive Ones
- [LeetCode]600. Non-negative Integers without Consecutive Ones
- leetcode 600. Non-negative Integers without Consecutive Ones
- [leetcode]600. Non-negative Integers without Consecutive Ones
- 600. Non-negative Integers without Consecutive Ones
- 600. Non-negative Integers without Consecutive Ones
- 600. Non-negative Integers without Consecutive Ones
- Leetcode 600 Non-negative Integers without Consecutive Ones
- leetcode 552. Student Attendance Record II & 600. Non-negative Integers without Consecutive Ones
- leetcode 600. Non-negative Integers without Consecutive Ones 非负整数不包括连续的1 + DP动态规划
- 第十五周:( LeetCode600) Non-negative Integers without Consecutive Ones(c++)
- LeetCode题解:Max Consecutive Ones
- leetcode题解-485. Max Consecutive Ones
- LEETCODE--Max Consecutive Ones
- LeetCode: Max Consecutive Ones
- 【leetcode】Max Consecutive Ones
- centos6 安装配置ActiveMQ笔记
- 微信小程序 —— 苹果机的兼容总结
- 【2】用jsoup来实现简单的java爬虫-图片篇
- linux下如何实现mysql数据库每天自动备份定时备份
- c#中using的三种用法
- LeetCode 600. Non-negative Integers without Consecutive Ones 题解
- 欢迎使用CSDN-markdown编辑器
- 关于Eclipse引入maven插件后,启动时maven报错的解决方案
- Tensorflow实战学习(十九)【序列分类、IMDB影评分类】
- 即将到来的Linux 4.15内核中RISC-V被合并的git log
- 技术动态 | 大规模中文概念图谱CN-Probase正式发布
- 有趣的数学
- 12款超强CSS3应用集锦下载
- springMVC框架初始化流程的初步理解