这里主要记录一下时间复杂度为 O(数的位数) 的方法,原作者大神的解答在:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/solution/mian-shi-ti-43-1n-zheng-shu-zhong-1-chu-xian-de-2/

对于一个整数,它的位数是多少位呢?不妨举几个例子:

  • 如果是99,很显然,它是两位
  • 100,是三位

可以用log10(m),即以10为底,m为给出的数来表示一个数能有多少位,如果m=99,那么这个式子约等于2,即两位;如果m=999,那这个式子差不多是3;如果m在(99, 999)范围内,那这个式子约等于2,也就是说我们可以用这个式子来大约的估计给出的数能有多少位。

得到了数m的位数,下面的算法就能做到在O(log(10)m)的时间内完成计算。

开始分析

对于一个数的每一位,把它分成三种情况:

  • 为0
  • 为1
  • 为2-9

用cur表示走到了当前位数,high表示高位,low表示低位,具体说明见下图:

现在分类讨论, 先看当前位数值是0的情况 ,我们以2304为例,假设当前位数是倒数第二位:

此时cur位置为1的数有多少个呢?固定cur位置为1,然后观察其他几位数的范围:

cur位置固定为1,那么想要统计数字中1出现的次数,最小值肯定是0010,因为0009就没有1了,最大值就是2219,因为十位(cur)固定为1,百位千位不能超过23,如果百位千位是23那就是2319了,比给出的数2304大,不符合题意。

这种情况下有多少个数字带1呢?其实就是看0010-2219,固定十位为1,其他位在这个范围内有多少种组合,不妨先用穷举法分析一下:

  • 固定千位为0(十位为始终1),那么从0010开始,一共有100个数里面带1:0010、0011、0012、…、0110、0111、0112、…、0910、0911、0912、…、0919,共100种。其实就是把千位0和十位1扣去,看剩下的百位和个位有多少种组合,很显然从00-99有100种组合;
  • 固定千位为1(十位为始终1),那么从1010开始,还是有100个数里面带1,原理和上面一样,把千位1和十位1扣去,还是百位和个位00-99的组合;
  • 固定千位为2(十位为始终1),那么从2010开始,一直到2219结束,一共有30个数里面带1,原理同上。
  • 综上,当cur到十位时,一共有 100+100+30 = 230 个数里面带1
  • 其实一个更简便的思路是,0010-2219,现在不是固定十位为1吗?那我就把十位扣去,剩下000-229,直接得出有230个数里面带1。

因此得出规律,如果cur当前位数的值为0,那么一共有 高位*cur所在位数(上例为10位) 的数带1,对上例来说,高位是23,cur所在位数是10位,那么一共有23*10=230个数里面带1。

再看当前位数值为1的情况 ,以2314为例,假设cur为倒数第二位,那么0010-2314范围内有多少个数带1呢?其实就是把十位扣出,剩下000-234,也就是有235个数会带1。

因此得出规律,如果cur当前位数的值为1,那么一共有 高位*cur所在位数(上例为10位) + 1 + 低位 的数带1,对上例来说,高位是23,cur所在位数是10位,低位是4,那么一共有23*10 + 1 + 4=235个数里面带1。

最后是当前位数值为[2-9]的情况,以2324为例,假设cur为倒数第二位,那么0010-2319范围内有多少个数带1呢?计算方法同上,把十位扣出,剩下000-239,也就是有240个数会带1。

因此得出规律,如果cur当前位数的值为[2-9],那么一共有 (高位+1)*cur所在位数(上例为10位) 的数带1,对上例来说,高位是23,cur所在位数是10位,那么一共有(23+1)*10=240个数里面带1。

还有一个问题,如果输入12,那么答案应该是5,因为1、10、11、12都包含1,11中包含两个1。那么上述分析能解决这个问题吗?

我们用230来分析:

  • cur在个位时,范围是001-221,有23个数包含1
  • cur在十位时,范围是010-219,有30个数包含1
  • cur在百位时,范围是100-199,有100个数包含1

cur在个位的范围中有11这个数,而cur在十位时,也有11这个数,这意味着11出现了两次,但上述的分析包含了这种情况,个位时有23个数包含1,十位时有30个数包含1,我们将他们相加就等于将11看成出现了两次。所以即便是一个数里有多个1,上面算法也能解决。

下面就开始写代码了,解析可以看开头贴出的大神原帖:

 int digit = 1;int res = 0, high = n / 10, cur = n % 10, low = 0;while (high != 0 || cur != 0) {if (cur == 0) res += high * digit;else if (cur == 1) res += high * digit + 1 + low;else res += (high+1) * digit;low += cur * digit;cur = high % 10;high /= 10;digit *= 10;}return res;

剑指offer43(leetcode 233),1-n整数中1出现的次数相关推荐

  1. 【LeetCode】剑指 Offer 43. 1~n 整数中 1 出现的次数

    [LeetCode]剑指 Offer 43. 1-n 整数中 1 出现的次数 文章目录 [LeetCode]剑指 Offer 43. 1-n 整数中 1 出现的次数 package offer;pub ...

  2. 剑指 Offer 43. 1~n 整数中 1 出现的次数(可能是最简洁易懂的)

    今天我们来看一道贼棒的题目,题目不长,很经典,也很容易理解,我们一起来看一哈吧, 大家也可能做过这道题,那就再复习一下,如果没做过的话,可以看完文章,自己去 AC 一下,不过写代码的时候,要自己完全写 ...

  3. 剑指 Offer 43. 1~n 整数中 1 出现的次数

    题目描述 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例如,输入12,1-12这些整数中包含1 的数字有1.10.11和12,1一共出现了5次. 题解 循环判断每一个位为出现1 ...

  4. 剑指 Offer 43. 1~n整数中1出现的次数

    思路: 当一个数是七位数, xyzMabc 如果M == 0,由于M以前的数字可以取0~xyz-1,共计xyz个,而每一个后面带M的都有0~999,共计1000个 xyz*1000 如果M==1,由于 ...

  5. 剑指 Offer 43. 1~n 整数中 1 出现的次数(数位dp)

    思路:就是数位dp,dp[idx][sum][limit]代表,到idx位,前面有sum个0,有没有limit限制: class Solution { public:int dp[20][50][2] ...

  6. 剑指Offer - 面试题56 - I. 数组中数字出现的次数(异或,分组)

    1. 题目 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字. 要求时间复杂度是O(n),空间复杂度是O(1). 示例 1: 输入:nums = [4 ...

  7. 剑指offer【43】:1-n中出现1的次数

    题目: 思路+代码: 法一:暴力法.遍历求和(超时) class Solution:def countDigitOne(self, n: int) -> int:# 暴力法超时if not n: ...

  8. java计算整数出现的次数_[剑指offer题解][Java]1到n整数中1出现的次数

    前言 众所周知,<剑指offer>是一本"好书". 如果你是个算法菜鸡(和我一样),那么最推荐的是先把剑指offer的题目搞明白. 对于剑指offer题解这个系列,我的 ...

  9. 【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I

    [LeetCode]剑指 Offer 53 - I. 在排序数组中查找数字 I 文章目录 [LeetCode]剑指 Offer 53 - I. 在排序数组中查找数字 I 一.二分法 总结 一.二分法 ...

最新文章

  1. 谈一谈安防行业人工智能发展情况
  2. Web服务器性能压力测试工具http_load、webbench、ab、Siege使用教程
  3. hibernate查询-基本查询
  4. java和net共同点,Java和.NET中的垃圾回收机制比较
  5. 如何使用SAP APF里的过滤器
  6. iOS十进制切割格式转换
  7. php 随机指定位数,php生成一个可选位数的随机码
  8. 最强动画制作人书包_声优访谈丨恋与制作人动画中配声优访谈——夏磊
  9. zabbix自动发现及其自动注册
  10. 采用光线跟踪绘制场景 c++_光线追踪必定是未来趋势,CJ现场带给你全新体验
  11. Not so Mobile UVA - 839
  12. DockerDesktop安装以后,控制台输入docker version报错This error may indicate that the docker daemon is not running
  13. Producter:让产品从0到1
  14. 百度搜索引擎推出“熊掌号”,保护原创作者权益
  15. t分布 u分布 卡方分布_t分布曲线和正太分布,和z分布,和卡方分布,和方差分析的f分布曲线有什么区别?...
  16. python对导入文件数据进行(查看、分析、解题思路、流程)做详细分析(适用于python初学者)
  17. (1366, Incorrect string value: '\\xE6\\xB7\\xB1\\xE5\\x85\\xA5...' for column '
  18. Linux中修改HTTP默认主页
  19. 'rm' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  20. 微软开源 Python 自动化神器 Playwright

热门文章

  1. java火柴人战争_《火柴人战争:遗产》兵种阵容搭配攻略
  2. 产品迭代团队协作敏捷流程图
  3. 商汤科技(上海)自动驾驶计算机视觉算法实习生面经-2020年10月
  4. 成为一名合格的ERP实施顾问应该具备哪些修为
  5. 计算机毕业设计ssm基于疫情防控下社区管理平台my3tu系统+程序+源码+lw+远程部署
  6. 一站式养老院看护系统现状分析,养老院智能看护系统伴你行-新导智能
  7. 跨境电商ERP系统高级功能介绍
  8. LeetCode题解(1217):黄金矿工(Python)
  9. php绕过管理员登录,EspCMS后台登录绕过漏洞再利用
  10. espcms自定义表单邮件字段