title
Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.
Example:
Input: 13
Output: 6
Explanation: Digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
solution
这个问题和n的阶乘中有多少个因数k不一样
solutionlink
solutionlink
int countDigitOne(int n)
{
int countr = 0;
for (long long i = 1; i <= n; i *= 10) {
long long divider = i * 10;
countr += (n / divider) * i + min(max(n % divider - i + 1, 0LL), i);
}
return countr;
}
- 考虑将n的十进制的每一位单独拿出讨论,每一位的值记为weight。
- 若weight为0,则1出现次数为
round*base - 若weight为1,则1出现次数为
round*base+former+1 - 若weight大于1,则1出现次数为
rount*base+base

public int count(int n){
if(n<1)
return 0;
int count = 0;
int base = 1;
int round = n;
while(round>0){
int weight = round%10;
round/=10;
count += round*base;
if(weight==1)
count+=(n%base)+1;
else if(weight>1)
count+=base;
base*=10;
}
return count;
也可以数位dp实现。 参考
class Solution:
def countDigitOne(self, n: int) -> int:
s = str(n)
import functools
@functools.lru_cache(None)
def f(i: int, ones: int, is_limit: bool, is_num: bool):
'''
:param ones: 1的个数
:return:
'''
if i == len(s):
return ones if is_num else 0
res = 0
if not is_num:
res += f(i + 1, 0, False, False)
up = int(s[i]) if is_limit else 9
for d in range(1 - int(is_num), up + 1):
res += f(i + 1, ones + (1 if d == 1 else 0), is_limit and d == up, True)
return res
return f(0, 0, True, False)