给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。
示例:
输入: 13
输出: 6
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 。
本题同【剑指Offer】面试题43. 1~n整数中1出现的次数
通过一个例子来找到规律,比如数字21345,我们把1-21345分为两部分,一段是1-1345,另一段是1346-21345。
本题中为了便于计算数字位数,将其转为字符串。
时间复杂度:O(logn),递归次数和位数相同,一个数字n有O(logn)位。
空间复杂度:O(1)
class Solution {
public:
int countDigitOne(int n) {
string str = to_string(n);
return helper(str);
}
int helper(string str) {
if (str.empty()) return 0;
int len = str.size();
int first = str[0] - ‘0‘;
if (len == 1 && first == 0) return 0;
if (len == 1 && first > 0) return 1;
int numFirst = 0;
if (first > 1) numFirst = pow(10, len - 1);
else if (first == 1) numFirst = stoi(str.substr(1)) + 1;
int numOther = first * (len - 1) * pow(10, len - 2);
int numRec = helper(str.substr(1));
return numFirst + numOther + numRec;
}
};
时间复杂度:O(logn)
空间复杂度:O(1)
class Solution {
public:
int countDigitOne(int n) {
if (n < 1) {
return 0;
}
int len = getLen(n);
if (len == 1) {
return 1;
}
int tmp = pow(10, len-1);
int first = n / tmp;
int firstOne = first == 1 ? n % tmp + 1 : tmp;
int otherOne = first * (len - 1) * (tmp / 10);
return firstOne + otherOne + countDigitOne(n%tmp);
}
int getLen(int n) {
int c = 0;
while (n) {
++c;
n /= 10;
}
return c;
}
};
原文:https://www.cnblogs.com/galaxy-hao/p/12897559.html