博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] Number of Digit One 数字1的个数
阅读量:5773 次
发布时间:2019-06-18

本文共 1802 字,大约阅读时间需要 6 分钟。

 

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出现的个数,之前有道类似的题,那道题是求转为二进数后1的个数,我开始以为这道题也是要用那题的方法,其实不是的,这题实际上相当于一道找规律的题。那么为了找出规律,我们就先来列举下所有含1的数字,并每10个统计下个数,如下所示:

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

1                   1                                                                                     [1, 9]

11                 111  111111119                              [10, 19]

1                   21                                                                                   [20, 29]

1                   31                                                                                   [30, 39]

1                   41                                                                                   [40, 49]

1                   51                                                                                   [50, 59]

1                   61                                                                                   [60, 69]

1                   71                                                                                   [70, 79]

1                   8                                                                                  [80, 89]

1                   91                                                                                   [90, 99]

11                 100  101  102  103  104  105  106  107  108  109          [100, 109]

21                 11111  11111111111111119             [110, 119]

11                 120  121  122  123  124  125  126  127  128  129          [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 = 0, a = 1, b = 1;        while (n > 0) {            res += (n + 8) / 10 * a + (n % 10 == 1) * b;            b += n % 10 * a;            a *= 10;            n /= 10;        }        return res;    }};

 

解法二:

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

 

类似题目:

 

参考资料:

 

转载地址:http://bwaux.baihongyu.com/

你可能感兴趣的文章
调用约定
查看>>
【转】ROS之topic和service通信比较
查看>>
[转]Linux 线程实现机制分析 Linux 线程实现机制分析 Linux 线程模型的比较:LinuxThreads 和 NPTL...
查看>>
lesson7:java线程池
查看>>
【2019年OCP新题】OCP题库更新出现大量新题-11
查看>>
N-Queens
查看>>
mysql允许远程连接
查看>>
PHP工厂模式的好处
查看>>
一道阿里笔试题
查看>>
【Android游戏开发之八】游戏中添加音频-详解MediaPlayer与SoundPoo!并讲解两者的区别和游戏中的用途!...
查看>>
Redis -- 数据类型小结
查看>>
数据库设计原则
查看>>
python3笔记<二> List
查看>>
ABP集成WIF实现单点登录
查看>>
模拟实现链栈
查看>>
条款9:绝不在构造和析构过程中调用virtual函数
查看>>
day8 socket编程CS模型完善错误处理
查看>>
Dzz任务板初版完成笔记-仿trello私有部署的一款轻量团队任务协作工具。
查看>>
线程基础8-quene讲解
查看>>
echarts - 使用echarts过程中遇到的问题(pending...)
查看>>