统计1到n之间的自然数中有多少个数字1出现
1. 题目描述
输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次。
在看了剑指offer上的解法之后,发现讲的不是很明晰,于是在网上查找了一下,看到了https://me.csdn.net/yi_Afly的解法,非常清晰明了,我也没法写的更好了,特转载如下:
2. 解题思路
考虑将n的十进制的每一位单独拿出讨论,每一位的值记为weight。
1) 个位
从1到n,每增加1,weight就会加1,当weight加到9时,再加1又会回到0重新开始。那么weight从0-9的这种周期会出现多少次呢?这取决于n的高位是多少,看图:
以534为例,在从1增长到n的过程中,534的个位从0-9变化了53次,记为round。每一轮变化中,1在个位出现一次,所以一共出现了53次。
再来看weight的值。weight为4,大于0,说明第54轮变化是从0-4,1又出现了1次。我们记1出现的次数为count,所以:
count = round+1 = 53 + 1 = 54
如果此时weight为0(n=530),说明第54轮到0就停止了,那么:
count = round = 53
2) 十位
对于10位来说,其0-9周期的出现次数与个位的统计方式是相同的,见图:
不同点在于:从1到n,每增加10,十位的weight才会增加1,所以,一轮0-9周期内,1会出现10次。即rount*10。
再来看weight的值。当此时weight为3,大于1,说明第6轮出现了10次1,则:
count = round*10+10 = 5*10+10 = 60
如果此时weight的值等于0(n=504),说明第6轮到0就停止了,所以:
count = round*10+10 = 5*10 = 50
如果此时weight的值等于1(n=514),那么第6轮中1出现了多少次呢?很明显,这与个位数的值有关,个位数为k,第6轮中1就出现了k+1次(0-k)。我们记个位数为former,则:
count = round*10+former +1= 5*10+4 = 55
3) 更高位
更高位的计算方式其实与十位是一致的,不再阐述。
4) 总结
将n的各个位分为两类:个位与其它位。
对个位来说:
若个位大于0,1出现的次数为round*1+1
若个位等于0,1出现的次数为round*1
对其它位来说,记每一位的权值为base,位值为weight,该位之前的数是former,举例如图:
则:
若weight为0,则1出现次数为round*base
若weight为1,则1出现次数为round*base+former+1
若weight大于1,则1出现次数为rount*base+base
比如:
534 = (个位1出现次数)+(十位1出现次数)+(百位1出现次数)=(53*1+1)+(5*10+10)+(0*100+100)= 214
530 = (53*1)+(5*10+10)+(0*100+100) = 213
504 = (50*1+1)+(5*10)+(0*100+100) = 201
514 = (51*1+1)+(5*10+4+1)+(0*100+100) = 207
10 = (1*1)+(0*10+0+1) = 2
5. 完整代码
public int count(int n){if(n<1)return 0;int count = 0;int base = 1;int round = n;while(round>0){int weight = round%10;round/=10;count += round*base;if(weight==1)count+=(n%base)+1;else if(weight>1)count+=base;base*=10;}return count;
}
6. 时间复杂度分析
由分析思路或者代码都可以看出,while循环的次数就是n的位数,logn(以10为底),而循环体内执行的操作都是有限次的,所以时间复杂度为O(logn)。
————————————————
版权声明:本文为CSDN博主「yi_afly」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yi_Afly/article/details/52012593
统计1到n之间的自然数中有多少个数字1出现相关推荐
- (PAT)统计给定区间内的三位数中有两位数字相同的完全平方数(如144、676)的个数
本题要求实现一个函数,统计给定区间内的三位数中有两位数字相同的完全平方数(如144.676)的个数. 函数接口定义: int search( int n ); 其中传入的参数int n是一个三位数的正 ...
- 【Java】1-100之间所有自然数的和(while和for方法)
目录 一.前言 二.代码部分 1.while语句 2.for语句 三.程序运行结果(控制台输出) 四.涉及到的知识点代码 一.前言 1.本代码是我在上学时写的,有一些地方没能完美实现,请包涵也请多赐教 ...
- 【LeetCode 每日一题】1617. 统计子树中城市之间最大距离(hard)
1617. 统计子树中城市之间最大距离 图论啊,那我先寄为敬.今天是代码搬运工. 题意很好理解啊,就是给你一个图,让你返回所有直径对应的子树的数量.是的没错,是所有直径,你不仅要枚举 1 − ...
- 使用js统计两个日期之间去掉(周六,周日)
使用js统计两个日期之间去掉(周六,周日) 写项目客户有个需求,要做一个休假申请,需要去掉休息日.今天就做了一个js的封装 js中一段时间中获取一段时间中的工作日,去掉星期六,星期日, 代码如下: e ...
- c语言编程输出100以内所有6的倍数的数,第8天学C语言(一点练习,例如打印1~100之间所有3的倍数的数字)...
(2020.9.12) 练习1:从大到小输出三个值 算法实现 a中放最大值 b次之 c最小 int a = 0; int b = 0; int c = 0; scanf_s("%d%d%d& ...
- 编写程序python输入任意大的自然数、输出各位数字之和_兰理工Python第一次上机作业源码...
1.编写程序,输入任意大的自然数,输出各位数字之和. a=input() sum=0 for i in a: sum=sum+int(i) print(sum) 运行结果: 2.编写程序,输入两个集合 ...
- 11-999之间的所有三重回文数字
问题描述:找出11-999之间的所有三重回文数字,所谓三重回文数a就是指a,a的平方,a的立方都是回文数字. 分析:1.首先要能判断一个数字是否为回文数字. 判断一个字符串是否为回文字符串是简单的,所 ...
- Java黑皮书课后题第7章:*7.11(统计:计算标准差)编程练习题5.45计算数字的标准差。本题…计算标准差,使用一个数组存储x的每个数。编写测试程序,提示用户输入10个数字,显示平均值和标准差
7.11(统计:计算标准差)编程练习题5.45计算数字的标准差.本题-计算标准差,使用一个数组存储x的每个数.编写测试程序,提示用户输入10个数字,显示平均值和标准差 题目 题目描述与运行示例 破题 ...
- 一个完全平方数是指一个数乘以自己,例:625=25^2; 特殊的完全平方数是指不仅是完全平方数而且平方后的数中有两个数字是相同的,例: 100=10^2; 144=12^2;
一人烤人曰..... 特殊的完全平方数 一个完全平方数是指一个数乘以自己,例:625=25^2; 特殊的完全平方数是指不仅是完全平方数而且平方后的数中有两个数字是相同的,例: 100=10^2; ...
最新文章
- 由oschina.neT了解到博客备份的代码
- 百度交易中台之账房系统架构浅析
- malloc分配内存的原理?
- 认清几种视频接口标准---无私奉献版
- java8 函数式编程_您必须学习Java 8的函数式编程吗?
- 总有一些人在祖国需要的时候挺身而出
- linux创建文件结构体,Linux file 结构体和 inode 结构体,Go语言入门技术,Go语言基础...
- http://blog.csdn.net/baidu_31657889/article/details/52315902
- Java 启动参数大全
- Q125:PBRT-V3,对比VolPathIntegrator::Li()和EstimateDirect()判断Medium的方式
- 怎样申请 Google Map apiKey
- 11. Django基础:应用及分布式路由
- ConstraintLayout使用汇总
- string容器模拟实现及使用——C++
- 推荐模型-上下文感知-2016:FNN模型【FM家族】【FM+MLP=FNN】
- android-23是什么手机,Android 8.1!首款helio P23/MT6763T手机曝光!
- 如何用Jmeter发送消息到Solace JNDI
- 使用mockserver来进行http接口mock
- wx:if 与wx:else
- 基于51单片机八路抢答器课程设计(含proteus仿真图及代码)
热门文章
- 无人机遥感测绘技术在工程测绘中的应用探究
- 微软学者奖学金2020名单出炉!中国高校八人上榜,清华表现最为亮眼
- 4-(二苯氨基)苯乙炔偶联苯乙酸酯-二碘代二苯乙烯基-氟硼荧(BODIPY)应用于DSSC
- 网吧无盘服务器游戏盘,影响无盘网吧游戏性能的虚拟盘服务器
- Process32First
- LINK : fatal error LNK1168: cannot open Debug/c_pub_test.exe for writing 解决方法
- 读《魔鬼经济学01》
- 惠普微型计算机t628电源,HSTNS-PL18 DPS-750RB A 506822-201 750W HP服务器电源
- java 数组成员_java 数组中含有
- html仿微信拆红包效果旋转,利用React加CSS3实现微信拆红包动画效果实例(代码)...