数字 1 的个数
难度:
标签:
题目描述
给定一个整数 n
,计算所有小于等于 n
的非负整数中数字 1
出现的个数。
示例 1:
输入:n = 13 输出:6
示例 2:
输入:n = 0 输出:0
提示:
0 <= n <= 109
代码结果
运行时间: 18 ms, 内存: 16.1 MB
/*
* Solution Idea using Java Streams:
* We can utilize Java Streams to streamline the process of counting '1's. By creating a range
* from 0 to n, we can use map and filter operations to count the occurrences of '1'. This
* approach provides a functional and concise way to implement the solution.
*/
import java.util.stream.IntStream;
public class Solution {
public int countDigitOne(int n) {
return IntStream.rangeClosed(0, n)
.map(Solution::countOnesInNumber)
.sum();
}
// Helper method to count the number of '1's in a single number
private static int countOnesInNumber(int num) {
int count = 0;
while (num > 0) {
if (num % 10 == 1) {
count++;
}
num /= 10;
}
return count;
}
}
解释
方法:
这个题解采用了逐位枚举的思路。对于给定的整数n,我们将其转为字符串s,然后从高位到低位逐个分析每一位上1出现的次数。对于第i位,我们将数字分为三部分:第i位之前的部分(记为pre)、第i位(记为now)以及第i位之后的部分(记为suf)。根据now的值,我们可以分三种情况统计第i位上1出现的次数:1)now=0时,ans+=pre*mul;2)now=1时,ans+=pre*mul+suf+1;3)now>1时,ans+=(pre+1)*mul。最后,将每一位统计的结果累加即可得到最终答案。
时间复杂度:
O(m),其中m为整数n的位数
空间复杂度:
O(m),其中m为整数n的位数
代码细节讲解
🦆
为什么在计算第i位上数字1的出现次数时,需要将数字分为pre、now和suf三部分?
▷🦆
当now=1时,为什么ans的计算方式是`ans += pre * mul + suf + 1`?具体是如何得出这个公式的?
▷🦆
对于now=0和now>1的情况,算法如何确保它们的计算方法正确反映了数字1的出现次数?
▷🦆
请解释变量`mul`在算法中的作用及其如何影响计算结果?
▷