问题描述

给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。
示例:
输入: 13
输出: 6
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 。

问题分析

这道题可以换一个思路,即[0,n]中有多少个小于n的第i位为1的数,例如n = 12345时,我们要找百位数为1时,存在多少数m小于12345,我们分为两部分,设\(m = p1q\),

  • 如果\(p\in[0,11]\)时,\(q\)可以取\([0,99]\)之间任意一个数,共100个,
  • 如果\(p = 12\)时,因为百位数字为\(3>1\),因此我们还是可以取\([0,99]\)之间任意一个数,共\(100\)个,但是假如\(n=12045\),这样的数是不存在的,因为任意\(121q>12045\),假如\(n=12145\),则只能取\([0,45]\)之间的数,共46个。

综上我们可以总结规律如下:我们统计从左到右的第i位为1小于n的数量时

  • 首先可以确定有\(\lfloor \frac{n}{10^{i+1}}\rfloor\times 10^i\)个数
  • 下面考虑第i位的数\(x = \lfloor\frac{n}{10^{i}}\rfloor\%10\),若\(x > 1\),则还会有\(10^i\)个数小于n,如果\(x = 1\),则会有\(n \% 10^i + 1\)个数小于n, 如果\(x = 0\),则不会有新的满足条件的数了

代码

class Solution {
public:
int countDigitOne(int n) {
int count=0,x;
long div = 1;
while(n>=div)
{
count += (n / (div*10))*div;
x = (n/div)%10;
if(x == 1)count += (n%div + 1)*x;
else if(x > 1) count += div;
div *= 10;
}
return count;
}
};

参考博客

最新文章

  1. PAT (Basic Level) Practise 1040 有几个PAT(DP)
  2. TortoiseSVN常用操作说明
  3. Java判断一个时间是否在另一个时间段内
  4. canvas保存为data:image扩展功能的实现
  5. {好文备份}SQL索引一步到位
  6. windows 环境下安装plpython语言环境到postgresql数据库
  7. encodeURI后台乱码(解决)
  8. 2016 ACM/ICPC Asia Regional Qingdao Online 1005 Balanced Game
  9. 我的 Github 个人博客是怎样炼成的
  10. .Net基础体系和跨框架开发普及
  11. (转)java并发之Executor
  12. Codeforces Round #436 B. Polycarp and Letters
  13. xpath爬取新浪天气
  14. quartz 实例
  15. hadoop家族成员
  16. RabbitMQ 高可用集群搭建
  17. 【敏捷】7.showcase,开发中必须引起重视的小环节
  18. 二、SQL的生命周期
  19. Tomcat入门级小白教程
  20. HTTP Error 502.5 - Process Failure asp.net core error in IIS

热门文章

  1. 联盛德 HLK-W806 (十): 在 CDK IDE开发环境中使用WM-SDK-W806
  2. Python3.6+Django2.0以上 xadmin站点的配置和使用
  3. java 编程基础 类加载器
  4. TFTP协议介绍-python实现tftp客户端
  5. 当更新user表时,页面没有的属性,执行update语句不会更改以前的值
  6. List集合取其中指定几条数据
  7. 【LeetCode】487. Max Consecutive Ones II 解题报告 (C++)
  8. 【LeetCode】837. New 21 Game 解题报告(Python)
  9. 【LeetCode】421. Maximum XOR of Two Numbers in an Array 解题报告(Python & C++)
  10. 【LeetCode】6. ZigZag Conversion Z 字形变换