题目描述
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
解:
这道题我们首先可以大概猜测出,1出现的次数跟位数有关。如果用位数直接对应有些麻烦,比如十位上的n(>1),会出现n+9次,但是n为百位,千位......上时规律比较难以求出,所以我们不采用这种方法。
我们可以把每个数位拆出来,比如十位,比如215,就会有11,12......19;111,112......119;211,212......215;可以看出这是由十位之前的数值所影响的,十位前面是2,所以十位上至少会有2*10次1的出现,本位和后位影响,5导致了5+1次的出现。显然百位同理,对于百位前的值为0,所以只剩本位,2,显然1已经过去了,所以从100......199共100个1存在。到这里我们可以推出规律,当current位的高位不为零时,本位一定至少会出现(高位*本位值),本位为0无影响,本位为1则有额外的(低位值+1)(因为0),本位为>1则直接(+本位值)。
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int cur=1;
//n原值还有用,所以用个t来迭代
int t=n;
int yu;
int sum=0;
while(t!=0){
yu=t%10;
//高位,也是下一轮需要的值
t/=10;
sum+=(t*cur);
if(yu==1){
sum+=(n%cur+1);
}
if(yu>1){
sum+=cur;
}
cur*=10;
}
return sum;
}
}
当然,还有一种最直接的方法,就是暴力求解,把n递减,然后转换成数组来计算每一个值的1个数...缺点是特别慢...
--end--