题目:
Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.
For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
题意:
给定一个数字n,统计从1到n的数字中1出现的次数。
思路:
对于一个数字比如4356,这是一个k=4位的数,即共有四位。先考虑最高位,当最高位是1的时候,满足的数字有1000~1999,共有10^3,但是如果是1356这样的数字,那么最高位是1的时候,一共有1000~1356,即356 +1个数字满足情况。
考虑完最高位后我们考虑剩下的三位,我们可以把数字分成两个部分,1~356,357~4356这两个部分。对于357~4356这个部分,考虑后三位是1的情况,我们可以把这段数字继续划分成四个部分,357~1356,1357~2356,2357~3356,3357~4356,每一部分有个特点就是无论最后三位哪一位上取1,其它两位可以取0~9,所以这四个部分1的个数是4*3*10^2 = 1200种可能。
刚才还有一部分1~356没有统计1的个数,观察后我们发现,这部分其实就是接下来需要递归的问题啊,因为原问题是1~n,接下来递归的部分是1~356。
综上,代码如下:
class Solution {
public:
int countDigitOne(int n) {
if(n < 10)
return (n > 0 ? 1 : 0);
int k = 1;
int tens = 10;
while(n / tens >= 1) {
k++;
tens *= 10;
}
return getOne(n, k);
}
int getOne(int n, int k) {
if(k == 1)return (n > 0)?1:0;
int tens = pow(10, k -1);
int high = n / tens;
int result = 0;
int last = n % tens;
if(high == 1)result += last + 1;
else if (high == 0) return getOne(last, k - 1);
else result += tens;
result += high * (k - 1) *(tens/10);
result += getOne(last, k - 1);
return result;
}
};