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 + ;
}
};

类似题目:

House Robber II

House Robber

Ones and Zeroes

参考资料:

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的更多相关文章

  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 ...

  2. 第十六周 Leetcode 600. Non-negative Integers without Consecutive Ones(HARD) 计数dp

    Leetcode600 很简单的一道计数题 给定整数n 求不大于n的正整数中 二进制表示没有连续的1的数字个数 在dp过程中只要保证不出现连续1以及大于n的情况即可. 所以设计按位dp[i][j]表示 ...

  3. [LeetCode] 128. Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  4. [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 ...

  5. Non-negative Integers without Consecutive Ones

    n位二进制,求不包含连续1的二进制(n位)数字个数. http://www.geeksforgeeks.org/count-number-binary-strings-without-consecut ...

  6. LeetCode--Longest Consecutive Sequence(最长连续序列) Python

    题目描述: Longest Consecutive Sequence(最长连续序列) 中文: 给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). 英文: Given ...

  7. [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 ...

  8. [LeetCode] Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  9. 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 ...

随机推荐

  1. 安装php扩展 ffmpeg-php

    环境: CentOS 6.5 PHP5.6 安装前php 已加载GD 模块(yum install php-gd)1.添加ffmpeg和ffmpeg-devel源 cat > /etc/yum. ...

  2. 【Java】0X001.配置开发环境,JDK、classpath等

    [Java]0x01 配置开发环境,JDK.CLASSPATH等 一. 下载JDK安装文件 首先,进入Oracle官网Java页面. 注意,要下载的是JDK而不是JRE,这点很重要,因为JRE并不包含 ...

  3. 读论文系列:Object Detection CVPR2016 YOLO

    CVPR2016: You Only Look Once:Unified, Real-Time Object Detection 转载请注明作者:梦里茶 YOLO,You Only Look Once ...

  4. [高级软件工程教学]团队Beta阶段成绩汇总

    一.作业地址: https://edu.cnblogs.com/campus/fzu/AdvancedSoftwareEngineering/homework/1501 二.Beta冲刺课堂答辩 1. ...

  5. C语言第二次作业

    一.PTA实验作业 题目1:7-1 计算分段函数[2] 1.实验代码 double x,y; scanf("%lf",&x); if (x>=0) { y=sqrt( ...

  6. 【Swift】 iOS开发容易产生Bug的地方

    1.隐藏navigationBar(尤其是多级隐藏) 2.共用collectionView或tableView 3.继承关系下,注意覆写父类时的super方法的调用 4.关于权限的问题(相机权限,相册 ...

  7. 在Windows上安装「算法 第四版」组件

    这篇文档将向你介绍如何在Windows系统上安装本书将用到的Java开发环境,同时我们也提供了一个手把手的.使用我们提供的DrJava工具或者用命令行来创建.编译和运行你的第一个Java程序的手册,这 ...

  8. tornado web高级开发项目

    抽屉官网:http://dig.chouti.com/ 一.配置(settings) settings = { 'template_path': 'views', #模板文件路径 'static_pa ...

  9. Webview之H5页面调用android的图库及文件管理

    h5页面打开图片管理器 一般页面在pc打开文件管理器是用 type="file"的代码,可是这在android的webview是无效的,必须为webview设定WebChromeC ...

  10. 北亚关于HP EVA4400/6400/8400/P6000的数据恢复解决方案

    [引言]本文档建立在针对HP EVA的大量测试性研究基础上,所有的细节几乎均为对EVA的破译型研究,目前全球范围内尚未发现类似资料,故可能表述方式和结论并不精确,仅为参考之用.我们公司为研究HP EV ...