[LeetCode] Non-negative Integers without Consecutive Ones 非负整数不包括连续的1
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 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.
Note: 1 <= n <= 109
这道题给了我们一个数字,让我们求不大于这个数字的所有数字中,其二进制的表示形式中没有连续1的个数。根据题目中的例子也不难理解题意。我们首先来考虑二进制的情况,对于1来说,有0和1两种,对于11来说,有00,01,10,三种情况,那么有没有规律可寻呢,其实是有的,我们可以参见这个帖子,这样我们就可以通过DP的方法求出长度为k的二进制数的无连续1的数字个数。由于题目给我们的并不是一个二进制数的长度,而是一个二进制数,比如100,如果我们按长度为3的情况计算无连续1点个数个数,就会多计算101这种情况。所以我们的目标是要将大于num的情况去掉。下面从头来分析代码,首先我们要把十进制数转为二进制数,将二进制数存在一个字符串中,并统计字符串的长度。然后我们利用这个帖子中的方法,计算该字符串长度的二进制数所有无连续1的数字个数,然后我们从倒数第二个字符开始往前遍历这个二进制数字符串,如果当前字符和后面一个位置的字符均为1,说明我们并没有多计算任何情况,不明白的可以带例子来看。如果当前字符和后面一个位置的字符均为0,说明我们有多计算一些情况,就像之前举的100这个例子,我们就多算了101这种情况。我们怎么确定多了多少种情况呢,假如给我们的数字是8,二进制为1000,我们首先按长度为4算出所有情况,共8种。仔细观察我们十进制转为二进制字符串的写法,发现转换结果跟真实的二进制数翻转了一下,所以我们的t为"0001",那么我们从倒数第二位开始往前遍历,到i=1时,发现有两个连续的0出现,那么i=1这个位置上能出现1的次数,就到one数组中去找,那么我们减去1,减去的就是0101这种情况,再往前遍历,i=0时,又发现两个连续0,那么i=0这个位置上能出1的次数也到one数组中去找,我们再减去1,减去的是1001这种情况,参见代码如下:
解法一:
class Solution {
public:
int findIntegers(int num) {
int cnt = , n = num;
string t = "";
while (n > ) {
++cnt;
t += (n & ) ? "" : "";
n >>= ;
}
vector<int> zero(cnt), one(cnt);
zero[] = ; one[] = ;
for (int i = ; i < cnt; ++i) {
zero[i] = zero[i - ] + one[i - ];
one[i] = zero[i - ];
}
int res = zero[cnt - ] + one[cnt - ];
for (int i = cnt - ; i >= ; --i) {
if (t[i] == '' && t[i + ] == '') break;
if (t[i] == '' && t[i + ] == '') res -= one[i];
}
return res;
}
};
下面这种解法其实蛮有意思的,其实长度为k的二进制数字符串没有连续的1的个数是一个斐波那契数列f(k)。比如当k=5时,二进制数的范围是00000-11111,我们可以将其分为两个部分,00000-01111和10000-10111,因为任何大于11000的数字都是不成立的,因为有开头已经有了两个连续1。而我们发现其实00000-01111就是f(4),而10000-10111就是f(3),所以f(5) = f(4) + f(3),这就是一个斐波那契数列啦。那么我们要做的首先就是建立一个这个数组,方便之后直接查值。我们从给定数字的最高位开始遍历,如果某一位是1,后面有k位,就加上f(k),因为如果我们把当前位变成0,那么后面k位就可以直接从斐波那契数列中取值了。然后标记pre为1,再往下遍历,如果遇到0位,则pre标记为0。如果当前位是1,pre也是1,那么直接返回结果。最后循环退出后我们要加上数字本身这种情况,参见代码如下:
解法二:
class Solution {
public:
int findIntegers(int num) {
int res = , k = , pre = ;
vector<int> f(, );
f[] = ; f[] = ;
for (int i = ; i < ; ++i) {
f[i] = f[i - ] + f[i - ];
}
while (k >= ) {
if (num & ( << k)) {
res += f[k];
if (pre) return res;
pre = ;
} else pre = ;
--k;
}
return res + ;
}
};
类似题目:
参考资料:
https://discuss.leetcode.com/topic/90571/java-solution-dp
https://discuss.leetcode.com/topic/90639/c-non-dp-o-32-fibonacci-solution
https://discuss.leetcode.com/topic/90671/java-o-1-time-o-1-space-dp-solution
http://www.geeksforgeeks.org/count-number-binary-strings-without-consecutive-1s/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Non-negative Integers without Consecutive Ones 非负整数不包括连续的1的更多相关文章
- [LeetCode] 298. Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...
- 第十六周 Leetcode 600. Non-negative Integers without Consecutive Ones(HARD) 计数dp
Leetcode600 很简单的一道计数题 给定整数n 求不大于n的正整数中 二进制表示没有连续的1的数字个数 在dp过程中只要保证不出现连续1以及大于n的情况即可. 所以设计按位dp[i][j]表示 ...
- [LeetCode] 128. Longest Consecutive Sequence 求最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...
- [LeetCode] 549. Binary Tree Longest Consecutive Sequence II 二叉树最长连续序列之 II
Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. Especia ...
- Non-negative Integers without Consecutive Ones
n位二进制,求不包含连续1的二进制(n位)数字个数. http://www.geeksforgeeks.org/count-number-binary-strings-without-consecut ...
- LeetCode--Longest Consecutive Sequence(最长连续序列) Python
题目描述: Longest Consecutive Sequence(最长连续序列) 中文: 给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). 英文: Given ...
- [Swift]LeetCode600. 不含连续1的非负整数 | Non-negative Integers without Consecutive Ones
Given a positive integer n, find the number of non-negativeintegers less than or equal to n, whose b ...
- [LeetCode] Longest Consecutive Sequence 求最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...
- 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 ...
随机推荐
- Hie with the Pie
Hie with the Pie poj-3311 题目大意:n+1个点,伪旅行商问题. 注释:n<=10. 想法:咳咳,第一道状压dp,下面我来介绍一下状压dp. 所谓dp,就是动态性决策规划 ...
- jdk 环境配置踩坑
其实在网上已经有很多环境配置的介绍了.不过我还是想用切身经历告诉大家这里面可能遇到的坑. 首先,先给大家讲一下JAVA_HOME,path,CLASSPATH JAVA_HOME 指向的是JDK的安装 ...
- hibernate框架学习笔记2:配置文件详解
实体类: package domain; public class Customer { private Long cust_id; private String cust_name; private ...
- JavaScript(第五天)【流程控制语句】
ECMA-262规定了一组流程控制语句.语句定义了ECMAScript中的主要语法,语句通常由一个或者多个关键字来完成给定的任务.诸如:判断.循环.退出等. 一.语句的定义 在ECMAScri ...
- C语言第二次作业---分支结构
一.PTA实验作业 题目1:计算分段函数[2] 1.实验代码 double x,y; scanf("%lf",&x); if(x>=0){ y=sqrt(x); } ...
- 【Alpha 阶段】后期测试及补充(第十一、十二周)
[Alpha 阶段]动态成果展示 修复了一些bug后,关于游戏的一些动态图展示如下: 终极版需求规格说明书和代码规范 经过一些细微的图片和格式的调整,完成了本学期的最终版本: [markdown版说明 ...
- 【iOS】Swift ?和 !(详解)
Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值, 也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化 .如果在使用变量之前不进行初始化就会报错: [ ...
- Jmeter读取文件中的值《一》
此篇主要是对应上一章节的呼应,上一篇中讲到将返回值写入文件,这个值如果在下一个接口中用到, 那么我们需要去从文件中读取数据,这是我们该如何操作? 一.测试计划中添加CSV Data Set Confi ...
- C# 封装miniblink 使用HTML/CSS/JS来构建.Net 应用程序界面和简易浏览器
MiniBlink的作者是 龙泉寺扫地僧 miniblink是什么? (抄了一下 龙泉寺扫地僧 写的简洁) Miniblink是一个全新的.追求极致小巧的浏览器内核项目,其基于chromium最新 ...
- react中的DOM操作
前面的话 某些情况下需要在典型数据流外强制修改子代.要修改的子代可以是 React 组件实例,也可以是 DOM 元素.这时就要用到refs来操作DOM 使用场景 下面是几个适合使用 refs 的情况 ...