Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

For example:

Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

Hint:

  1. Beware of overflow.

这道题让我们比给定数小的所有数中1出现的个数,之前有道类似的题 Number of 1 Bits,那道题是求转为二进数后1的个数,博主开始以为这道题也是要用那题的方法,其实不是的,这题实际上相当于一道找规律的题。那么为了找出规律,我们就先来列举下所有含1的数字,并每10个统计下个数,如下所示:

1的个数          含1的数字                                                                        数字范围

1                                                                                                        [1, 9]

11                 0    2  3  4  5  6  7  8  9                              [10, 19]

1                   2                                                                                   [20, 29]

1                   3                                                                                   [30, 39]

1                   4                                                                                   [40, 49]

1                   5                                                                                   [50, 59]

1                   6                                                                                   [60, 69]

1                   7                                                                                   [70, 79]

1                   81                                                                                   [80, 89]

1                   9                                                                                   [90, 99]

11                 00  0  02  03  04  05  06 07  08  09          [100, 109]

21                 0    2  3  4  5  6  7  8  9             [110, 119]

11                 20  2  22  23  24  25  26  27  28  29          [120, 129]

...                  ...                                                                                  ...

通过上面的列举可以发现,100 以内的数字,除了10-19之间有 11 个 ‘1’ 之外,其余都只有1个。如果不考虑 [10, 19] 区间上那多出来的 10 个 ‘1’ 的话,那么在对任意一个两位数,十位数上的数字(加1)就代表1出现的个数,这时候再把多出的 10 个加上即可。比如 56 就有 (5+1)+10=16 个。如何知道是否要加上多出的 10 个呢,就要看十位上的数字是否大于等于2,是的话就要加上多余的 10 个 '1'。那么就可以用 (x+8)/10 来判断一个数是否大于等于2。对于三位数区间 [100, 199] 内的数也是一样,除了 [110, 119] 之间多出的10个数之外,共 21 个 ‘1’,其余的每 10 个数的区间都只有 11 个 ‘1’,所以 [100, 199] 内共有 21 + 11 * 9 = 120 个 ‘1’。那么现在想想 [0, 999] 区间内 ‘1’ 的个数怎么求?根据前面的结果,[0, 99] 内共有 20 个,[100, 199] 内共有 120 个,而其他每 100 个数内 ‘1’ 的个数也应该符合之前的规律,即也是 20 个,那么总共就有 120 + 20 * 9 = 300 个 ‘1’。那么还是可以用相同的方法来判断并累加1的个数,参见代码如下:

解法一:

class Solution {
public:
int countDigitOne(int n) {
int res = , a = , b = ;
while (n > ) {
res += (n + ) / * a + (n % == ) * b;
b += n % * a;
a *= ;
n /= ;
}
return res;
}
};

解法二:

class Solution {
public:
int countDigitOne(int n) {
int res = ;
for (long k = ; k <= n; k *= ) {
long r = n / k, m = n % k;
res += (r + ) / * k + (r % == ? m + : );
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/233

类似题目:

Factorial Trailing Zeroes

Digit Count in Range

参考资料:

https://leetcode.com/problems/number-of-digit-one/

https://leetcode.com/problems/number-of-digit-one/discuss/64390/AC-short-Java-solution

https://leetcode.com/problems/number-of-digit-one/discuss/64381/4+-lines-O(log-n)-C++JavaPython

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Number of Digit One 数字1的个数的更多相关文章

  1. 233 Number of Digit One 数字1的个数

    给定一个整数 n,计算所有小于等于 n 的非负数中数字1出现的个数. 例如: 给定 n = 13, 返回 6,因为数字1出现在下数中出现:1,10,11,12,13. 详见:https://leetc ...

  2. [Leetcode] Number of Digit Ones

    Given an integer n, count the total number of digit 1 appearing in all non-negative integers less th ...

  3. LeetCode Number of Digit One

    原题链接在这里:https://leetcode.com/problems/number-of-digit-one/ 每10个数, 有一个个位是1, 每100个数, 有10个十位是1, 每1000个数 ...

  4. [CareerCup] 18.4 Count Number of Two 统计数字2的个数

    18.4 Write a method to count the number of 2s between 0 and n. 这道题给了我们一个整数n,让我们求[0,n]区间内所有2出现的个数,比如如 ...

  5. [LeetCode] Number of 1 Bits 位1的个数

    Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also know ...

  6. [LeetCode] Number of Distinct Islands 不同岛屿的个数

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  7. LeetCode Number of 1 Bits 计算1的个数

    题意: 提供一个无符号32位整型uint32_t变量n,返回其二进制形式的1的个数. 思路: 考察二进制的特性,设有k个1,则复杂度为O(k).考虑将当前的数n和n-1做按位与,就会将n的最后一个1去 ...

  8. LeetCode OJ 之 Number of Digit One (数字1的个数)

    题目: Given an integer n, count the total number of digit 1 appearing in all non-negative integers les ...

  9. [Swift]LeetCode233. 数字1的个数 | Number of Digit One

    Given an integer n, count the total number of digit 1 appearing in all non-negative integers less th ...

随机推荐

  1. 3.C#WinForm基础累加器

    功能:实现累加计算. 知识点: bool int.TryParse(string s,out int result)(+1重载) 将数字的字符串形式转换为它的等效的32位有效的有符号整数,一个指示操作 ...

  2. 剖析 HTTP 协议

    HTTP 概述 HTTP 是什么? HTTP(HyperText Transfer Protocol,超文本传输协议)是WWW (World Wide Web)实现数据通信的基石. HTTP是由IET ...

  3. H5天气查询demo(二)

    最近刚好有空,学长帮忙让做个毕设,于是我提到了那个基于H5地理位置实现天气查询的方法,学长听了也觉得不错,于是就这个主题,扩展了一下,做了一个航班管理查询系统,为上次博客中提到的利用H5 api中的经 ...

  4. [Tool] 插入折叠区域功能

    之前写了一个 仿博客园网页端推荐的插入代码插件, 后来在总结一些技术文档时,总是想把一些属性或者方法,参数等,都用表格的形式清晰的列举出来,但是插入的表格太大的话,上下跨度就显得特别大,来回上下滚动的 ...

  5. MVC采用Jquery实现局部刷新

    该文纯粹属于个人学习,有不足之处请多多指教! 效果图: 单击Detail下面出现详细,效果如下: 为了使操作时两个不同的数据源相互干扰,使用局部视图刷新,代码如下: 首先介绍主页Index代码: @m ...

  6. 设计模式(十二)享元模式(Flyweight Pattern)

    一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非 ...

  7. 学习之路~sqh

    推荐博客 Edison Chou: Vamei: 算法∙面试专题 - 简书: 设计模式 极速理解设计模式系列[目录索引]- Caleung: Net设计模式 - 灵动生活: 宅男程序员给老婆的计算机课 ...

  8. VMware12下安装Debian8.5

    参考:  Debian 8.2.0 (Jessie) 快速纯净安装教程    Debian 7 安装配置总结    Debian 7.8 系统安装配置过程 软件包管理命令    包命令    从源代码 ...

  9. Maven对插件进行全局设置

    并不是所有插件都适合从命令行配置,有些参数的值从项目创建到发布都不会改变,或者很少改变,对于这种情况,在POM文件中一次性配置就显然比重复在命令行中输入要方便了. 用户可以在生命插件的时候,对插件进行 ...

  10. Spring+ibatis动态管理数据源

    Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...