剑指 Offer 43. 1~n 整数中 1 出现的次数
思路:数学
设数字n是个x位数,记n的第i位为 n i n_i ni,则可将n写为 n x n x − 1 ⋯ n 2 n 1 n_xn_{x-1}\cdots n_2 n_1 nxnx−1⋯n2n1;
- 记 n i n_i ni为当前位,记作cur
- 记 n i − 1 n i − 2 ⋯ n 2 n 1 n_{i-1}n_{i-2}\cdots n_2 n_1 ni−1ni−2⋯n2n1为low
- 记 n x n x − 1 ⋯ n i + 2 n i + 1 n_xn_{x-1}\cdots n_{i+2}n_{i+1} nxnx−1⋯ni+2ni+1为high
- 记 1 0 i 10^i 10i为因子,记为digit
根据当前位cur的不同,分为以下三种情况:
1.cur=0时:cur出现1的次数由高位high决定,计算公式为:
h i g h × d i g i t high\times digit high×digit
2.cur=1时:cur出现1的次数由high和low决定,计算公式为:
h i g h × d i g i t + l o w + 1 high\times digit+low+1 high×digit+low+1
3.cur=2,3,…9时:cur出现1的次数由高位high决定,计算公式为:
( h i g h + 1 ) × d i g i t (high+1)\times digit (high+1)×digit
class Solution {
public:
int countDigitOne(int n) {
int high=n/10,cur=n%10,low=0,res=0;
long digit=1;
while(high||cur){
if(cur==0) res+=high*digit;
else if(cur==1) res+=high*digit+low+1;
else res+=(high+1)*digit;
low+=digit*cur,cur=high%10,high/=10,digit*=10;
}
return res;
}
};
时间复杂度 O(logn)
空间复杂度 O(1)