题目描述:给你一个整数,计算出从[1,n],的所有包含1的数字的个数
思路:
分割这个数,按照1,10,100的递增,可以用一个循环实现
为什么要分割,为了分开计算1出现的次数,每次定位到某一个位上面
总用有三种情况:
(1)假设一个数33452, 假设定位到100,那么a=33452/100=334,b=33452%100=52。
百位的数是大于1的,先假设定位这个百位就是1了,百位因为只有一种可能是1,然后因为百位大于1,所以当百位为1的时候,那么低于百位的数随便是多少了,这样的话 就由100种可能 (0~100)。然后计算高于百位的数让这个百位的1能有多少次出现的次数,a=334那么 百位为1可能的次数为a/10+1=34 (0~33), 所以总的次数为 (a/10+1)*100
(2)假设一个数33152, 假设定位到100,那么a=33152/100=331,b=33452%100=52。
百位的数为1,那么定位为百位为1的时候就不能把(0~33)中的第33个百位为1的时候算成有100个了,因为此时最大为52,所以 最后的次数为 (a/10)*100 +b+1 为什么是b+1 因为(0~52)有53个数
(3)假设一个数33052, 假设定位到100,那么a=33152/100=331,b=33452%100=52。
百位数为0,那么就需要高位退一位才能有1的出现,因此 百位为1出现的次数为 a/10 =33 (0~32,退了一位),所以此时的次数为(a/10)*100
java实现:
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int res =0;
for( int i=1;i<=n;i=i*10){
int a = n/i,b=n%i;
if(a%10==0){
res += (a/10)*i;
}else if(a%10==1){
res += (a/10)*i + b+1;
}else{
res += (a/10+1)*i;
}
}
return res;
}
}