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.
题目只能通过寻找规律来实现。以2234为列,我们可以分为两段计算,一段是1-234, 一段是235 - 2234,我们可以发现1-234其实求的是234前面的1的个数,也就是说我们可以递归的来求了。在求解235-2234的的1的个数时,1出现的地方分两种情况,一个是出现在第一位,这种情况的话,要看第一位是不是1,如果第一位是1,那么就可以是后面三位数字 +1;如果第一位不是1,那么就是pow(10, len - 1); 这是1在第一位的情况,1在后面几位的情况,我们可以用排列组合,可以知道其值为: 第一位的值 * (len - 1) * pow(10, len - 2); 这样分析之后,就可以快速的实现代码了。
int countOne(string str)
{
int len = str.size();
if(len == 0 || (len == 1 && str[0] == '0'))
return 0;
if(len == 1 && str[0] != '0')
return 1;
string tmpstr = str.substr(1, str.size() - 1);
int numFirstDigit = 0;
if(str[0] == '1')
{
numFirstDigit = atoi(tmpstr.c_str()) + 1;
}
else if(str[0] > '1')
{
numFirstDigit = pow(10.0, len - 1);
}
int numOtherDigit = (str[0] - '0') * (len - 1) * pow(10.0, len - 2);
int numRecursive = countOne(tmpstr);
return numFirstDigit + numOtherDigit + numRecursive;
}
int countDigitOne(int n) {
if(n <= 0)
return 0;
return countOne(to_string(n));
}