剑指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. 在ubuntu系统荣品开发配套JDK安装
  2. POJ 2186 popular cow 有向图的强联通问题 Tarjan算法
  3. gatekeeper学习概述
  4. Windows消息机制以及相关API
  5. DPlayer播放器本地化P2P解析加速版源码
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的大学生兼职网站
  7. 【OpenCV应用】python处理行李图像匹配项目——图像直方图应用与明暗变换
  8. 关于Oracle返回值
  9. Linux开机启动流程详细步骤是什么?
  10. Linux运维第二课----Linux发展史、环境准备
  11. i2c-tools 使用集锦
  12. SiteMesh3使用介绍及配置方法
  13. 创新彰显实力,方正璞华又获一项国家发明专利
  14. Birds in Forest
  15. const T 与T const(const T vs.T const的翻译 Dan Saks)
  16. 2020中兴开发岗笔试题
  17. FeignClientSpecification could not be registered
  18. Unknown database ‘ ‘
  19. Maven问题之Lastupdated
  20. 仿百度地图抽屉拖拽效果

热门文章

  1. 港科夜闻丨香港科大(广州)获国家教育部批准筹建,南沙校址举办动工仪式...
  2. 用户留存率详解与计算方法案例
  3. 论韩剧如何影响一个人
  4. html字号24怎么设置,css怎么设置字体大小
  5. Pytorch数组反转(数组倒序)函数flip的使用
  6. 同志社交应用程序 Hornet 获得 800 万美元 A 轮融资,银泰资本领投
  7. (详细图示)IDEA彻底删除项目
  8. 如何使用Solidworks使得出图更加逼真
  9. 网络模型:HTTTP、TCP、UDP简介
  10. 服务质量QoS(Quality of Service)的基础知识