剑指offer中的题目:从1到n整数中1出现的次数

本文是我做这题的思路,整理出来方便自己以后查看,也欢迎大家的讨论。

题目

输入一个正整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12。1一共出现了5次。

思路

1.暴力解法

暴力解法就是从头到尾说每个数中1的个数,然后求和。数每个数中1的个数需要的复杂度为O(logn),而每个数都需要数一遍,因此总的算法复杂度为O(nlogn)。

2.递归法

递归法就是把数按位对数进行拆分,一步一步缩小数的规模,比如 n=23417 时,可以把问题拆为1–3417和3418–23417,每步先对后一部分进行计算,前一部分可以看成 n=3417 时的求解。这样就可以先分析下 3418–23417 一共有多少个1呢?首先这些数中包含 10000~19999 这一万个第一个数字为1的数。就是先算下和后面一个数位数相同时第一个数字为1的数一共多少个。后面一个数去掉第一个数字后还有4位,这4为每一个位上都能为1,当其中一位为1时,其它3位可以是 0-9 这10个数中的任何一个,因此一共的个数位 4 ∗ 3 10 4*3^{10} 4∗310,又由于第一个数位2,因此3418–23417的1的总个数位 2 ∗ 4 ∗ 3 10 2*4*3^{10} 2∗4∗310,最高位从1到2后面的数重复两遍。我在做这一题的时候,前期有点疑惑的时,在排列组合后面4位数时,这个方法没有考虑重复的情况,假如第一位选了1,第二个数从0-9 10个数都选一遍,然后第二个数选了1时,第一个数又从 0-9 10个数选了一遍,这就出现了两次两个都为1的数,是不是重复计算了?后来仔细想想发现并没有,因为每个位只计算在他的位上出现1的次数,比如刚才说的出现两个数都是1的情况,这时当每个位选1时只算了一次,但其实这个数有两个1,因此后面的再算一次才能把1都统计了,这个问题是统计数字1出现的次数,不是每个数的情况,一个数中存在几个1都要加进去
代码如下:

def numberof1temp(n):if 0 < n < 10:return 1if n <= 0:return 0sum_1 = 0str_n = str(n)len_n = len(str_n)temp = int(str_n[1:])first_number = int(str_n[0])numberoffirst = numberof1firstnumber(str_n)sum_1 += numberoffirstnumberofleft = first_number * (len_n - 1) * 10**(len_n-2)sum_1 += numberofleftsum_1 += numberof1temp(temp)return sum_1def numberof1firstnumber(str_n):first_number = int(str_n[0])if first_number > 1:number = 10**(len(str_n)-1)else:number = int(str_n[1:]) + 1return number

3.编程之美上的解法

通过分析,可以发现:
1到10,个位数是1的个数是:1
1到100,十位数是1的个数是:10
1到1000,百位数是1的个数是:100
因此可以通过看这些数包含几个10,几个100,几个1000来计算1出现的次数。还以23417为例,从1到23417要包括多少个10?数数时:1, 2,3, 4, 5, 6, 7, 8, 9,10,然后1,2, 3, 4, 5, 6, 7, 8, 9, 20,再数 1,2, 3, 4, 5, 6, 7, 8, 9, 30。可以看出除了十位数发生了变化,只是相当于个位数重复了一遍。在数数时,大家也经常只数个位数,从1到10数一遍记一下,这样方便好数。十位数同理。 23417 ÷ 10 = 2341 23417\div10=2341 23417÷10=2341 那个位数上出现的1的个数就是 2341 + 1 2341+1 2341+1之所以加1是因为从2341-2347,个位还会再出现一个1。这个思路从数数只数个位数,数完一遍记下数,比较好理解。在写代码时,有一点需要注意的是,循环时数n的值不应该每次变为n//base,而应该改变base为10*base,因为n//base的余数是需要留下来计算的,余数中1出现的次数不能忘了。比如在算十位上1出现的次数时 23417 ÷ 100 = 234 23417\div100=234 23417÷100=234,1出现的次数 234 ∗ 10 234*10 234∗10,余数17十位上1出现的次数也要算进去的, 234 ∗ 10 234*10 234∗10只算了 1-23400 中十位上1出现的次数,还有 23401-23417 中十位上1出现的次数。
代码如下:

def numberof1(n):sum_1 = 0base = 10while n//(base//10):m = n // baseb = n % baseif b >= 2 * base//10:b_sum = base//10elif b >= 1 * base//10:b_sum = b % (base//10) + 1else:b_sum = 0sum_1 += m * base//10 + b_sumbase *= 10return sum_1

总结

在理解算法时,需要记得计算的是所有数中1出现的次数,也就是后面两个算法中分别考虑每个位上1出现的次数。

从1到n整数中1出现的次数(python 实现)相关推荐

  1. shell最大出现和连续出现次数_从 1 到 n 整数中 1 出现的次数

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  2. 剑指offer:整数中1出现的次数(从1到n整数中1出现的次数)

    题目描述 求出1-13的整数中1出现的次数,并算出100-1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  3. 【刷算法】整数中1出现的次数(从1到n整数中1出现的次数)

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  4. 从1到n整数中1出现的次数

    从1到n整数中1出现的次数 题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次, ...

  5. 整数中1出现的次数(从1到n整数中1出现的次数)

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  6. 30 整数中1出现的次数(从1到n整数中1出现的次数)这题很难要多看*

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  7. 《剑指offer》-- 数组中的逆序对、最小的K个数、从1到n整数中1出现的次数、正则表达式匹配、数值的整数次方

    一.数组中的逆序对: 1.题目: 数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出 ...

  8. 《剑指offer》整数中1出现的次数(从1到n整数中1出现的次数)

    题目:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了.AC ...

  9. 《剑指offer》第四十三题(从1到n整数中1出现的次数)

    // 面试题43:从1到n整数中1出现的次数 // 题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如 // 输入12,从1到12这些整数中包含1 的数字有1,10,11和12 ...

最新文章

  1. Hadoop集群中运行MapReduce程序错误记录
  2. python面向对象基础
  3. PCB设计过孔选用指导
  4. React Native实现NbaApp
  5. 数据看穿一生:前半生赚钱养娃,后半生赚钱买命
  6. mac终端编写c语言,【新手提问】有知道用mac终端编c语言的网络编程的人吗?
  7. Spring-aop-TargetSource/ProxyFactory/DefaultAopProxyFactory
  8. pd虚拟机 17.1.2 Intel核心Mac专用版
  9. BBS论坛(二十三)
  10. CSDN用户服务条款
  11. NLP任务增强:通过引入外部知识库来提供额外信息
  12. 三星董事长去世享年78岁,临终前最为遗憾的一件事
  13. 关于Redis出现“java.io.IOException: 远程主机强迫关闭了一个现有的连接”的一次排查
  14. 调试SQL SERVER存储过程
  15. 掩膜区域内像素值_OpenCV计算机视觉学习(2)——图像算术运算 图像阈值(数值计算,掩膜mask操作,边界填充,二值化)...
  16. 公开课:如何做一个合格的网络编辑
  17. 编写程序计算算例系统的潮流及三相短路电流(Matlab)
  18. 123457123456#3#----com.ppGame.konglongPuzzle78--前拼后广--konglongPT游戏_pp
  19. 操作系统-最近最久未使用置换算法
  20. 湖北9月计算机二级报名时间,[最新]云南省湖北省2019年9月全国计算机二级报名时间公布...

热门文章

  1. java实现频繁项集_java实现Apriori算法——频繁项集的计算
  2. 伊家田园与湖南亚美生物达成合作,携手打造垂直农业新社交电商
  3. 微积分大笑话,误人子弟
  4. 【区块链技术工坊26期实录】张东光:区块链+医疗应用实践探讨
  5. fcpx插件:PremiumVFX Comic Titles(手绘漫画风格的标题和背景)
  6. python中if有多个条件_Python中if有多个条件处理方法
  7. 王学岗Linux系统的使用和Linux命令
  8. MOOC程序设计入门——C语言(翁恺)第五周编程作业“念整数”
  9. 跟Howard学LESS之初见LESS
  10. Acwing《算法基础课》第3章 搜索与图论