**
剑指offer43题 1-N整数中1出现的次数
**
题解:
总体思想就是分类,先求所有数中个位是 1 的个数,再求十位是 1 的个数,再求百位是 1 的个数…
假设 n = xyzdabc,此时我们求千位是 1 的个数,也就是 d 所在的位置。
那么此时有三种情况,
d == 0,那么千位上 1 的个数就是 xyz * 1000
d == 1,那么千位上 1 的个数就是 xyz * 1000 + abc + 1
d > 1,那么千位上 1 的个数就是 xyz * 1000 + 1000
为什么呢?
当我们考虑千位是 1 的时候,我们将千位定为 1,也就是 xyz1abc。
对于 xyz 的话,可以取 0,1,2…(xyz-1),也就是 xyz 种可能。
当 xyz 固定为上边其中的一个数的时候,abc 可以取 0,1,2…999,也就是 1000 种可能。
这样的话,总共就是 xyz*1000 种可能。
注意到,我们前三位只取到了 xyz-1,那么如果取 xyz 呢?
此时就出现了上边的三种情况,取决于 d 的值。
d == 1 的时候,千位刚好是 1,此时 abc 可以取的值就是 0 到 abc ,所以多加了 abc + 1。
d > 1 的时候,d 如果取 1,那么 abc 就可以取 0 到 999,此时就多加了 1000。
示例:
如果n = 4560234
让我们统计一下千位有多少个 1
xyz 可以取 0 到 455, abc 可以取 0 到 999
4551000 to 4551999 (1000)
4541000 to 4541999 (1000)
4531000 to 4531999 (1000)
...
21000 to 21999 (1000)
11000 to 11999 (1000)
1000 to 1999 (1000)
总共就是 456 * 1000
如果 n = 4561234
xyz 可以取 0 到 455, abc 可以取 0 到 999
4551000 to 4551999 (1000)
4541000 to 4541999 (1000)
4531000 to 4531999 (1000)
...
1000 to 1999 (1000)
xyz 还可以取 456, abc 可以取 0 到 234
4561000 to 4561234 (234 + 1)
总共就是 456 * 1000 + 234 + 1
如果 n = 4563234
xyz 可以取 0 到 455, abc 可以取 0 到 999
4551000 to 4551999 (1000)
4541000 to 4541999 (1000)
4531000 to 4531999 (1000)
...
1000 to 1999 (1000)
xyz 还可以取 456, abc 可以取 0 到 999
4561000 to 4561999 (1000)
总共就是 456 * 1000 + 1000
代码
public class offer43 {
//记录1的个数
int cnt=0;
public int NumberOf1Between1AndN_Solution(int n) {
//按个位、十位、百位上1得个数相加之和
for (int i = 1; i <=n;i*=10) {
//求取对应位的商
int m=n/i;
//对应位的余数
int a=n%i;
//将三种情况合并
//如果对应位<=1,+8不会影响/10后结果,
//如果>1,加8后原来/10后结果基础上+1,满足了对应位大于1的情况
cnt+=(m+8)/10*i +(m%10==1 ? a+1:0);
}
return cnt;
}
}
再看一个具体的例子。
链接:https://leetcode-cn.com/problems/number-of-digit-one/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-50/
来源:力扣(LeetCode)