https://leetcode-cn.com/problems/number-of-digit-one/
思路:答案就是
n
n
n的每一位(个位、十位、百位…)上出现的1的数量的总和。那么对于任意一个数字
a
b
c
d
e
abcde
abcde,假设计算
c
c
c位上的1,且有
h
i
g
h
=
a
b
,
c
u
r
=
c
,
l
o
w
=
d
e
,
d
i
g
i
t
=
1
0
2
high=ab,cur=c,low=de,digit=10^2
high=ab,cur=c,low=de,digit=102,现在开始分类讨论
c
c
c的取值:
- c = 0 c=0 c=0,为了让这一位取1,同时整个数字不能大于 a b c d e abcde abcde,高位 h i g h high high只能取 [ 0 , h i g h − 1 ] [0,high-1] [0,high−1],此时低位可以任意取,因此1的总数为: h i g h ∗ d i g i t high*digit high∗digit。举个例子, n = 1204 n=1204 n=1204,为了让十位取1,高位只能取 [ 0 , 11 ] [0,11] [0,11],此时低位可以取 [ 0 , 9 ] [0,9] [0,9]任意一个数,因此1的总数为:12*10=120。
- c = 1 c=1 c=1,情况1仍然成立,但是当高位 h i g h high high取最大时,低位不能任意取了,最多只能取到 d e de de,因此1的总数为: h i g h ∗ d i g i t + l o w + 1 high*digit+low+1 high∗digit+low+1。举个例子, n = 1214 n=1214 n=1214,考虑 h i g h = 12 , c u r = 1 high=12,cur=1 high=12,cur=1的情况, l o w low low只能取 [ 0 , 4 ] [0,4] [0,4],因此1的总数为:12*10+5=125。
- c > 1 c>1 c>1,情况1依然成立,且高位 h i g h high high取最大、该位取1时,低位依然能够任意取: h i g h _ 1 _ a n y < h i g t _ c _ l o w high\_1\_any<higt\_c\_low high_1_any<higt_c_low,因此1的总数为: ( h i g h + 1 ) ∗ d i g i t (high+1)*digit (high+1)∗digit。
class Solution {
public:
int countDigitOne(int n) {
long long high=n/10,cur=n%10,low=0,digit=1,ans=0;
while(high||cur){
if(cur==0)
ans+=high*digit;
else if(cur==1)
ans+=high*digit+low+1;
else
ans+=(high+1)*digit;
low+=cur*digit;
cur=high%10;
high/=10;
digit*=10;
}
return ans;
}
};