从1到n整数中1出现的次数
输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含“1”的数字有1,10,11和12,其中“1”一共出现了5次。
思路:
假如说有abcdef位,当我们有任以数在c处为1,_ 1 _ _
大致分为00到ab和00~ab-1这两种
00到ab 的话 中间的1是根据边界条件而定是否存在
00到ab-1 由于进位数学等常理,1肯定存在
在1的前面有两位,就有00~ab-1 这么多情况也就是十进制数ab这么多种
在1的右边有三位,就有000~999这么1000种情况。
此时 的一的个数就为 ab* 1000
然后判断边界00~ab的情况,
如果c=1此时右边还有def种情况,一的个数还要加上 000~def 也就是def+1种
如果c=0没有用了,没有一不管
如果c>1 则说明还能有000~999种(数学性质,只要大于1有新的进位就有1000个数)一的个数再加上1000;
这里的c可以换成abcdef任意一个别的数,所以用for循环从最左往右遍历,每个位都像上面c位那样操作,最后得到的就是结果
总结:
就是当每一位上是1时考虑其他位
宏观上分为00…~abc…-1和00…到abc…-1两种情况
第二种要计算边界情况。。。。
public int numberOf1Between1AndN_Solution(int n) {
if(n==0)return 0;
String str = n+"";
int[] m = new int[str.length()];
for(int i =str.length()-1; i >=0; i--)
{
//先由字符串转换成char,再转换成String,然后Integer
m[str.length()-1-i] = Integer.parseInt( String.valueOf(str.charAt(i)));
}
int res = 0;
for(int i=m.length-1;i>=0;i--){
int left = 0,right = 0,t =1;
for(int j =m.length-1;j>i;j--){//得到左边的数字
left =left*10 + m[j];
}
for(int j = i-1;j>=0;j--){//得到右边的数字
right = right*10 +m[j];
t = t*10;//统计该位是多少;
}
//开始统计个数
res = res+left*t;
if(m[i]==1){
res+=right+1;
}else if(m[i]>1){
res+=t;
}
}
return res;
}
original ideal from acwing