题目:输入一个整数n,求 1-n 这 n 个整数的十进制表示中 1 出现的次数。例如,输入12, 1-12 中这些整数中包含1的数字有1、10、11 和 12, 1 一共出现 5 次。
方法一:暴力法,时间复杂度为 O(nlogn)
直接循环遍历求出 n 个数中每一个数包含 1 的次数,然后累加起来。
//方法一:暴力法
public int NumberOf1Between1AndN_Solution(int n){
int number = 0;
for (int i=1; i <= n; i++){
number = number + numbersOf1(i);
}
return number;
}
private int numbersOf1(int n) {
int numbers = 0;
while (n > 0){
if (n % 10 == 1){
numbers++;
}
n = n/10;
}
return numbers;
}
方法二:从数字规律入手,时间复杂度为O(logn)。
思路:参考 这篇博客
public int NumberOf1Between1AndN_Solution(int n){
if(n<1) return 0;
int count = 0; //计数器
int base = 1; //从个位数开始基数为1,十位数的基数为10...
int round = n;
while(round>0){
//表示十进制的每一位,从各位数开始
int weight = round % 10;
//表示每一次weight位上的数要从0-9变换多少个轮回
round = round / 10;
//当weight位上为0的时候
count = count + round * base;
if(weight==1){
count= count + (n % base)+1;
}
else if(weight>1){
count= count + base;
}
//下一位的基数为前一位基数的十倍
base= base * 10;
}
return count;
}