不包含连续1的非负整数

给定一个正整数 n,找出小于或等于 n 的非负整数中,其二进制表示不包含 连续的1 的个数。

示例 1:

输入: 5

输出: 5

解释:

下面是带有相应二进制表示的非负整数<= 5:

0 : 0

1 : 1

2 : 10

3 : 11

4 : 100

5 : 101

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

说明: 1 <= n <= 109

思路

考虑一种比较简单的情况,如果n=2^k - 1,其中k为正整数,那么问题就变成二进制数00……0(k个0)到11……1(k个1)中有几个数不包含连续的1,设答案为f(k)。

我们可以考虑k位二进制数的第一位:如果第一位是0,那么第二位既可以取0也可以取1,也就是说对后面的k-1位无影响,所以第一位为0的满足条件的数总共有f(k-1)个;如果第一位是1,那么由于不能出现连续的1,第二位只能取0,但是对后面的k-2位无影响,所以第一位为1的满足条件的数总共有f(k-2)个。

这样,我们就得到了:f(k) = f(k-1) + f(k-2)。边界条件为f(1)=2以及f(2)=3,由于f(0)=1满足原问题的题意也满足上述的转移方程,故可以取边界条件f(0)=1,f(1)=2。

对于n不是2^k-1的一般情况,与上一点的不同之处在于:上一点中只要满足二进制位长度不超过k,那么这个数就不会超过n=2^k - 1,而这种情况需要具体考虑不超过n的数。

假设n的二进制有k位,最高位为1,其二进制为1xx……x(x表示0或1),那么0到n可分为00……0(k个0)到011……1(一个0,k-1个1)和100……0(一个1,k-1个0)到1xx……x(即n)两个部分。

前一个部分即0到2^(k-1)-1,这部分中满足条件的答案为f(k-1);第二部分则需进一步讨论:如果n的二进制从左往右第二位为1,即n的形式为11x……x,那么因为题目要求不能有连续的1,所以这一位只能取0,这样的数一定小于n,所以后k-2位不受大小的限制,答案为f(k-2),并结束计算;如果n的二进制从左往右第二位为0,即n的形式为10x……x,那么为满足不超过n的条件,第二位也只能取0,这样问题就变为从100……0到10x……x之间有多少满足条件的数,这样就可以继续对n的二进制的后k-2位进一步进行类似的讨论。

举个例子,n=10,二进制为1010:

对于最高位的1,我们将0到1010分为0到111和1000到1010两部分,前一部分的个数为f(3) = 5。

第二部分为1000到1010,最高位确定取1,而n的二进制从左往右第二位为0,为满足不超过n的条件,满足条件的数从左往右第二位只能取0。

n的二进制从左往右第三位为1,这样我们又可以按i中的方法,把1000到1010再次分成1000到1001和1010两个部分,前一部分的个数为f(1) = 2。

到n的最低位,为0,故最后一位只能取0,按照之前的算法这一步不会增加答案,但由于n=1010b本身还没有计入,故再加1。

最后得到答案5+2+1=8。

n的二进制长度为log(n),故该算法的时间复杂度为O(log(n))。

第一种情况示意

第二种情况示意:

 class Solution {
public int findIntegers(int num) {
if(num==0) return 1;
String binary = Integer.toBinaryString(num);
int len=binary.length();
int[] f = new int[len+1];
f[0]=1;
f[1]=2;
//计算场i的二进制位符合要求的个数
for(int i=2; i<=len; i++) {
f[i] = f[i-1]+f[i-2];
}
//计算0~n的符合要求的总个数
int sum=0;
for(int i=0, k=len; i<len; i++,k--) {
if(binary.charAt(i)=='1') {
sum+=f[k-1];
if(i>0 && binary.charAt(i-1)=='1') {
return sum;
}
}
}
//先前没有return,到这里,说明n本身没有算进去
sum++;
return sum;
}
}

Leetcode 600.不包含连续1的非负整数的更多相关文章

  1. Java实现 LeetCode 600 不含连续1的非负整数(有些题为了避免使用位运算可以换成动态规划)

    600. 不含连续1的非负整数 给定一个正整数 n,找出小于或等于 n 的非负整数中,其二进制表示不包含 连续的1 的个数. 示例 1: 输入: 5 输出: 5 解释: 下面是带有相应二进制表示的非负 ...

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

    给定一个正整数 n,找出小于或等于 n 的非负整数中,其二进制表示不包含 连续的1 的个数. 例如: 输入: 5 输出: 5 解释: 下面是带有相应二进制表示的非负整数<= 5: 0 : 0 1 ...

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

  4. LeetCode 581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)

    581. 最短无序连续子数组 581. Shortest Unsorted Continuous Subarray 题目描述 给定一个整型数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序 ...

  5. [LeetCode] Contains Duplicate 包含重复值

    Given an array of integers, find if the array contains any duplicates. Your function should return t ...

  6. [LeetCode] Continuous Subarray Sum 连续的子数组之和

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

  7. LeetCode(485. 最大连续1的个数)

    问题描述 给定一个二进制数组, 计算其中最大连续1的个数. 示例 1: 输入: [1,1,0,1,1,1] 输出: 3 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3. 注意: ...

  8. Leetcode 581.最短无序连续子数组

    最短无序连续子数组 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, ...

  9. 图解leetcode —— 128. 最长连续序列

    前言: 每道题附带动态示意图,提供java.python两种语言答案,力求提供leetcode最优解. 描述: 给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). ...

随机推荐

  1. ubuntu14.04server下安装scala+sbt工具

    安装sbt参考https://www.cnblogs.com/wrencai/p/3867898.html 在安装scala时 首先得安装jdk环境,最好安装最新版本以免后续安装出现不必要的麻烦 一. ...

  2. 【微软大法好】VS Tools for AI全攻略(3):低配置虚拟机也能玩转深度学习,无需NC/NV系列

    接着上文,现在我们需要一种穷人的方法来搭建好Azure虚拟机. 思路很简单,因为AI组件的原理其实是传送了script文件和命令上去,那么我们这个虚拟机只要做好了所有的配置,那么我们就可以将它当作深度 ...

  3. swift 命名空间实现的设计思考:extension YKKit where Base == String

    设计问题:谁来构造.构造什么.怎么添加新功能 关键词:本体.客体.构造.映射.功能. 别名:桥接变量.型变变量.容器变量.适配变量,构造变量: 目的:添加命名空间.添加新功能. 原则:不修改本体的实现 ...

  4. 【洛谷4424】[HNOI/AHOI2018] 寻宝游戏(位运算思维题)

    点此看题面 大致题意: 给你\(n\)个\(m\)位二进制数.每组询问给你一个\(m\)位二进制数,要求你从\(0\)开始,依次对于这\(n\)个数进行\(and\)或\(or\)操作,问有多少种方案 ...

  5. 第九章 利用DOM脚本检索,替换,设置,追加样式信息

    我们浏览器里看到的网页是由以下三层信息构成的一个共同体: -结构层,由HTML或XHTML之类的标记语言负责去搭建文档的结构. -表示层,由CSS负责设置文档的呈现效果. -行为层,由JavaScri ...

  6. LigerUi中表(Grid)控件的相关属性笔记

    http://blog.csdn.net/dxnn520/article/details/8216560 // ========================================= [每 ...

  7. react 信用卡格式检验

    前言: 技术栈主要基于react + ant-design 描述: 填写信用卡卡号时,会自动四位空格,并格式校验判断卡种  ,这里我们业务只涉及到四种卡. 代码解析 // ant 组件自引,这里我只讲 ...

  8. react的redux无状态组件

    Provider功能主要为以下两点: 在原应用组件上包裹一层,使原来整个应用成为Provider的子组件 接收Redux的store作为props,通过context对象传递给子孙组件上的connec ...

  9. C/C++程序基础 (九)排序算法简述

    排序算法 算法复杂度 算法简述 插入排序 N2 前方有序,依次将后方无序数据插入前方合适位置. 冒泡排序 N2 前方有序,从后方两两比较,将最小泡冒到前方. 选择排序 N2 前方有序,从后方选择最小的 ...

  10. Java中json前后端日期传递处理

    这里推荐2种方式 依赖包 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifa ...