从1到n整数出现的次数

题目:
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。

这个题目我想来一个小时,看别人的优秀代码看不懂,唉,菜是原罪,我就自己用自己的想法写出来了,大家可以参考一下

public int NumberOf1Between1AndN_Solution(int n) {
		String num = String.valueOf(n);
		int sum = 0;
		for(int i=0;i<num.length();i++) {
			int a = Integer.parseInt(num.substring(num.length()-i-1, num.length()-i));
			if(a>1) {		//当前位的数值大于1
				if(i==0) {		//这个是专门为个位数设置的
					sum+=1;
				}else {	//这个是普遍的
					sum+=i*Math.pow(10, i-1)*a+Math.pow(10, i);
				}
			}else if(a==1) {		//当位数的值等于1时
				if(num.substring(num.length()-i, num.length()).equals("")){//防止个位数为1,为1就加1
					sum+=1;  	
				}else {		//下面这个是当前位是1时,1的个数的统计
					 int index=Integer.parseInt(num.substring(num.length()-i, num.length()));
					sum+=index+i*Math.pow(10, i-1)*a+1;	
				}	
			}
			//这里没有当位数为0的时候
		}
		return sum;
	    
    }

现在解析一下这个解答的过程
首先看一张图
在这里插入图片描述
这张图就是这个程序的精华所在,不知道你看懂了不,现在就来介绍介绍这张图

首先上面这张图是以12345为例子,是以1到123451出现的例子的示范图

这些头上和底下的数全部加起来就是1出现的个数,

那就一个一个来解析首先个位5它1出现的次数肯定是1,
或者说,只要是大于等于1的个位数,那它的1的数量肯定是1
那就可以推导到十位,只要十位上的数是大于1的,那肯定1出现的次数是大于10的(虽然这里面有10到19有11个数字1的出现,但是我把他们拆开了,变成10x十位上的数字+10(这个10必须是十位大于1))

可能上面还是有点乱,那就看例子:
40中1出现的次数为4x1+10,20出现的次数为2x1+10
这样差不多清楚了吧,而这里面的10就是数字头顶上的
百位是把100到199拆开了,举个例子:200的1出现的次数是20x2+100,头顶上就是100

上面介绍了头顶上的数字,但是位数上的数字都是大于1的啊,如果等于1或0呢?
别慌,分析一下,如果等于0,那说明1出现的次数和这个位置没有关系,就肯定没有头顶上固定1出现次数的数字,当然如果是1,那也好办,就是头顶上的固定数字变成后面的数字+1,因为要考虑到后面位数都是0的情况。举个例子:101,这样百位上固定的次数是2也就是1+1

现在搞定了这些数字头上的那下边的呢?
其实下面的就是我拆开的另一部分和位数上的值相乘当然还有10的次方相乘,你可以分开看,先别看后面乘的位数的值,看前面两个值,你看像不像当前位变成1,后面的位数全都成0的数1出现的次数-1;
上面有点绕,举例子:300下的数字前两个相乘是不是1到99中1出现次数的和?
肯定是啊,1x10+10=20,那后面那个就是当前位是几就乘几,300说明循环了三次1到99,
前面位数的底下的数就可求了,
那就以2000为例子,那2000底下的数怎么用规律求?
那可以先求1000的,300不是已经出来1到99中1出现的次数了吗?那就乘10,再加上100(是100到199中1出现的次数减1),就成了1到999中1出现的次数,以此类推就可以求出全部的,而你会得出这么一个规律,就像上面图画的一样,底下的三个数一个自增,一个是10的自增的次方,还有一个是当前位的值,这样就完成了

上面可能讲的不咋地,但是也是我慢慢写出来的,请见谅啊

发布了213 篇原创文章 · 获赞 22 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_43113679/article/details/100022665
今日推荐