一道算法题-从1到n整数中1出现的次数
1. 题目描述
输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次。
2. 题目来源
第一次看到是在《剑指Offer》第2版上,面试题32。leetcode和牛客网上都有这道题。
3. 本文的目的
看了《剑指Offer》上的解法,我觉得不能算好:
- 这段解释描述有些不清晰,而且没有图,难以理解。
- 从书中给出的实现上来看,显得有些凌乱。
在这篇博客里,会给出一个我对这道题的解法,包括完整的解题思路,完整代码,时间复杂度分析。
4. 解题思路
考虑将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. 完整代码
int NumberOf1Between1AndN_Solution(int n)
{
if(n<)
return ;
int count = ;
int base = ;
int round = n;
while(round>)
{
int weight = round%;
round/=;
count += round*base;
if(weight==)
count+=(n%base)+;
else if(weight>)
count+=base;
base*=;
}
return count;
}
6. 时间复杂度分析
由分析思路或者代码都可以看出,while循环的次数就是n的位数,logn(以10为底),而循环体内执行的操作都是有限次的,所以时间复杂度为O(logn)。
参考文献:http://blog.csdn.net/yi_afly/article/details/52012593
一道算法题-从1到n整数中1出现的次数的更多相关文章
- 【剑指Offer面试编程题】题目1373:整数中1出现的次数--九度OJ
题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他.问题是:求出1~13的整数中1出现的次数,并算出100~130 ...
- 每天一道算法题(4)——O(1)时间内删除链表节点
1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...
- 30 整数中1出现的次数(从1到n整数中1出现的次数)这题很难要多看*
题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...
- 算法: 整数中1出现的次数(从1到n整数中1出现的次数)
问题: 整数中1出现的次数(从1到n整数中1出现的次数) 问题:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数? 为此他特别数了一下1~13中包含1的数字有1.10.11 ...
- 《剑指offer》第四十三题(从1到n整数中1出现的次数)
// 面试题43:从1到n整数中1出现的次数 // 题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如 // 输入12,从1到12这些整数中包含1 的数字有1,10,11和12 ...
- 编程算法 - 从1到n整数中1出现的次数 代码(C)
从1到n整数中1出现的次数 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一个整数n, 求从1到n这n个整数的十进制表示中1出现的次数. ...
- 九度OJ 1373 整数中1出现的次数(从1到n整数中1出现的次数)
题目地址:http://ac.jobdu.com/problem.php?pid=1373 题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU ...
- 剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数)
剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数) 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https:// ...
- n个整数中1出现的次数
整数中1出现的次数(从1到n整数中1出现的次数) (两种方法:1.规律.2暴力求解) 题目描述 求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下 ...
随机推荐
- 3dsmax2012卸载/安装失败/如何彻底卸载清除干净3dsmax2012注册表和文件的方法
3dsmax2012提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dsmax2012失败提示3dsmax2012安装未完成,某些产品无法安装,也有时候想重新 ...
- cuda9.0 中不存在libnppi.so
编译一个caffe版本,报错找不到 -lnppi 发现使用打是cuda9.0, 但是cuda9.0 中不存在libnppi.so. 只好换成cuda8.0.
- idea的插件zookeeper
平时用惯了ZooInspector,偶然知晓了idea的这个插件,试了一下感觉挺方便的 由于开发环境在内网,所以这里介绍内网方式(外网更简单). 1.下载插件 http://plugins.jetbr ...
- 008-PageBean类模板
1 PageBean模板一 package ${enclosing_package}; import java.util.ArrayList; import java.util.List; publi ...
- 从零实现一个简易的jQuery框架之二—核心思路详解
如何读源码 jQuery整体框架甚是复杂,也不易读懂.但是若想要在前端的路上走得更远.更好,研究分析前端的框架无疑是进阶路上必经之路.但是庞大的源码往往让我们不知道从何处开始下手.在很长的时间里我也被 ...
- bzoj 4709: [Jsoi2011]柠檬
Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从 ...
- 深入理解JavaScript系列(49):Function模式(上篇)
介绍 本篇主要是介绍Function方面使用的一些技巧(上篇),利用Function特性可以编写出很多非常有意思的代码,本篇主要包括:回调模式.配置对象.返回函数.分布程序.柯里化(Currying) ...
- plpgsql insert 性能 测试
有时需要执行一些sql脚本,带逻辑控制语句,又不想用高级语言C#.Java之类的,可以直接用plpgsql,类似于Oracle的plsql. do language 'plpgsql' $$ decl ...
- mybatis学习之动态sql
mybatis的动态sql语句很强大,在mapper映射文件中使用简单的标签即可实现该效果,下面一个个记录: 1.select查询 简单的select类似如下: <select id=" ...
- 一、URL和URLConnection
一.简述: 在Java网络编程中,我们最常听到的一个单词是URL.URL标识了一个资源,并可以通过URL来获取这个资源.我们不知道资源具体是什么,也不需要关心怎么获取.你只需要拿到一个URL,你就可以 ...