题目描述
给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。
输入: 13
输出: 6
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 。
参考代码
《剑指offer》第43题,解法见书。
从“数字规律”着手,通过具体的例子一步步找出规律。
C++语言版
class Solution {
public:
int countDigitOne(int n){
if(n <= 0)
return 0;
string str = to_string(n);
return mySolutionRecursively(str);
}
int mySolutionRecursively(string str){ // eg: 21345
int length = str.size();
if(length == 1){
if(str[0] == '0')
return 0;
else
return 1;
}
int firstNum = str[0] - '0';
int amountOfFirstDigit = 0;
if(firstNum == 1) // 当firstNum == 0时,此时amountOfFirstDigit == 0
amountOfFirstDigit = stoi(str.substr(1)) + 1;
else if(firstNum > 1)
amountOfFirstDigit = (int)pow(10, length-1);
int amountOfOtherDigit = 0;
amountOfOtherDigit = firstNum * (length-1) * (int)pow(10, length-2);
return amountOfFirstDigit + amountOfOtherDigit + mySolutionRecursively(str.substr(1));
}
};
C语言版
class Solution {
public:
int countDigitOne(int n)
{
if(n <= 0)
return 0;
char strN[50];
sprintf(strN, "%d", n);
return mySolutionRecursively(strN);
}
int mySolutionRecursively(char *str){
int length = strlen(str);
if(length == 1){
if(str[0] == '0')
return 0;
else
return 1;
}
int firstNum = str[0] - '0';
int amountOfFirstDigit = 0;
if(firstNum == 1)
amountOfFirstDigit = (int)atoi(str+1) + 1;
else if(firstNum > 1)
amountOfFirstDigit = (int)pow(10, length-1);
int amountOfOtherDigit = 0;
amountOfOtherDigit = firstNum * (length-1) * (int)pow(10, length-2);
return amountOfFirstDigit + amountOfOtherDigit + mySolutionRecursively(str+1);
}
};