题目描述:JZ43 整数中1出现的次数(从1到n整数中1出现的次数)
思路1:动态规划
- 状态表示:dp[i]
- 集合:从 1~n 整数中 1 出现的次数
- 属性:次数
- 状态计算:依据当前数字是否包含 1
- 包含 1:dp[i-1] + 1
- 不包含 1:dp[i-1]
时间复杂度:O(n),空间复杂度:O(n)
注意:当 n 的范围,超过,dp数组储存不下,过不了
#include <vector>
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n) {
if (!n) return 0;
vector<int> dp(30001, 0);
dp[0] = 0;
for (int i = 1; i <= n; ++i) {
int time = 0;
int x = i;
while (x) {
int y = x % 10;
if (y == 1) time++;
x /= 10;
}
dp[i] = dp[i-1]+time;
}
return dp[n];
}
};
思路2:按位统计法
时间复杂度:O(logn),空间复杂度:O(1)
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n) {
long long mulk = 1;
int res = 0;
for (int k = 0; n >= mulk; ++k) {
res += (n / (mulk * 10)) * mulk + \
min(max(n % (mulk * 10) - mulk + 1, 0LL), mulk);
mulk *= 10;
}
return res;
}
};