题目
输入一个整数n,求从1到n这n个整数的十进制表示中1出现从次数。
例如输入12,从1到12这12个数中包含1的数字:1,10,11,12;1总共出现了5次;
实现
思路:求出一个数中1的个数,可以使用除法、取余;求1到n的n个数,循环==此方法n较大时,费时;
高效方法:分别求出每位出现1的次数,再将每位出现1 的次数相加;
分析:
假设数字为abcde;我们分析百位出现1的次数:
1)当c=0, ab0de
百位出现1的:
00100–00199
01100–01199
…….
(ab-1)100–(ab-1)199
所以一共:ab*100+0
2)当c=1,ab1de
百位出现1的:
除了1)中的之外,(ab-1)200–ab1de之间出现1的:
ab100–ab1de
所以一共:ab*100+(de+1)
3)当c>1,比如ab3de
除了1)中的之外,(ab-1)200–ab3de之间出现1的:
ab100–ab199
所以一共:ab*100+(100)
===>
个位出现1的次数=n/10+(个位=0,0;个位>1,1;个位=1,1)
十位出现1的次数=n/100+(十位=0,0;十位>1,10;十位=1,个位数字+1)
百位出现1的次数=n/1000+(百位=0,0;百位>1,100;低二位+1)
…….
代码实现:
public static int countOf1(int n){
int num=n;
int N=0;
//计算n的位数
while(num!=0){
num=num/10;
N++;
}
int count=0;
//遍历每一位
for(int i=1;i<=N;i++){
count+=n/test(i)*test(i-1);
int temp=n/test(i-1)%10; //第i位数字
if(temp==1){
count+=n%test(i-1)+1;//n%test(i-1)
}
if(temp>1){
count+=test(i-1);
}
}
return count;
}
/*
* num=1--1
* num=2--10
* num=3--1000
* ......
* 第num位为多少?
*/
private static int test(int num) {
if(num==0){
return 1;
}
int res=1;
for(int i=1;i<=num;i++){
res=res*10;
}
return res;
}