
AcWing 56 从1到n整数中1出现的次数
当当前位数字大于1时。 当当前位数字等于1时。 当当前位数字等于0时。 处理特殊情况:如果输入n为0,返回0,因为没有数字“1”。 提取数字:将n转换为各个位上的数字。 遍历每一位:从最高位到最低位逐一分析每个数字的贡献。 计算左边部分:左边部分是当前位右边的所有数字组成的数。 计算右边部分:右边部分是当前位左边所有数字组成的数,并根据位权进行计算。 计算贡献并累加:根据当前位数字的值,对总贡献进行调整。
发布日期:2021-05-28 16:30:44
浏览次数:32
分类:精选文章
本文共 1818 字,大约阅读时间需要 6 分钟。
计算从1到n中数字“1”出现次数的高效方法
问题描述
给定一个整数n,要求计算从1到n中所有整数的十进制表示中数字“1”出现的总次数。
解决思路
为了高效解决这个问题,我们需要采取一种数学上的分解与分析方法,而不是简单地逐一枚举和计算(这种方法在n较大的情况下会导致时间复杂度过高)。以下是详细的分析方法:
数字的结构分解
当我们将一个数用十进制表示时,可以将其视为一个多位数的结构。例如,数123可以表示为百位、十位、个位的三个部分:1,2,3。
我们可以从右到左逐步分析每一位数字的贡献。这个方法的核心是从低位到高位逐步计算每一位数字“1”出现的次数,并结合其所在的位权来计算总贡献。
每一位的贡献分析
假设我们分析的是当前数的第i位(从右往左数,第一位是个位,第二位是十位,依此类推)。我们需要计算以下三种情况:
然后,我们结合当前位的位权来计算总贡献。
位权计算方法
对于第i位,位权是10的(i-1)次方。例如,个位的位置是1(10^0),十位的位置是10(10^1),依此类推。
具体计算步骤
假设我们有一个数n,十进制表示为d_k d_{k-1} ... d_1,其中d_k是最高位,d_1是个位。
我们需要对每一位d_i进行分析:
构造左边部分(高位)和右边部分(低位)。
- 左边部分:所有比当前位更高位的数字组成的数。
- 右边部分:所有比当前位低位的数字组成的数。
计算左边部分的最大值和右边部分的可能值。
- 如果当前位数字等于1,则左边部分可以唯一确定,右边部分可以从000到999任意变化。
- 如果当前位数字大于1,则左边部分可以从左边最高位到d_{i+1}-1变化,右边部分从000到999任意变化。
- 如果当前位数字等于0,则左边部分可以从左边最高位到d_{i+1}变化,右边部分从000到999任意变化。
根据上述情况计算当前位的贡献。
- 当前位数字为1时,贡献为右边部分数目加1。
- 当前位数字大于1时,贡献为左边最大值乘以右边数目。
- 当前位数字小于1时,无需额外贡献(因为数字不可能是“1”)。
代码实现示例
以下是一个实现了上述逻辑的C++代码:
int numberOf1Between1AndN(int n) { if (n == 0) return 0; vector digits; while (n) { digits.push_back(n % 10); n /= 10; } int ans = 0; for (int i = digits.size() - 1; i >= 0; --i) { int left = 0; int right = 0; int power = 1; for (int j = digits.size() - 1; j > i; --j) { left = left * 10 + digits[j]; } for (int j = i - 1; j >= 0; --j) { right = right * 10 + digits[j]; power *= 10; } ans += left * power; if (digits[i] == 1) { ans += right + 1; } else if (digits[i] > 1) { ans += power; } } return ans;}
代码解释
这种方法的时间复杂度与数字的位数有关,而不是与n的大小有关,因此它是高效的。
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月09日 15时04分16秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
在Vue中使用样式——使用内联样式
2019-03-07
Explore Optimization
2019-03-07
解决数据库报ORA-02289:序列不存在错误
2019-03-07
map[]和map.at()取值之间的区别
2019-03-08
成功解决升级virtualenv报错问题
2019-03-08
【SQLI-Lab】靶场搭建
2019-03-08
【Bootstrap5】精细学习记录
2019-03-08
Struts2-从值栈获取list集合数据(三种方式)
2019-03-08
参考图像
2019-03-09
设计模式(18)——中介者模式
2019-03-09
推荐几篇近期必看的视觉综述,含GAN、Transformer、人脸超分辨、遥感等
2019-03-09
BUU-MISC-caesar
2019-03-09
【专题3:电子工程师 之 上位机】 之 【46.QT音频接口】
2019-03-09
一文理解设计模式--命令模式(Command)
2019-03-09
VTK:可视化之RandomProbe
2019-03-09
block多队列分析 - 2. block多队列的初始化
2019-03-09