计算数字k在0到n中的出现的次数,k可能是0~9的一个值

计算数字k在0到n中的出现的次数,k可能是0~9的一个值

样例

例如n=12,k=1,在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],我们发现1出现了5次 (1, 10, 11, 12)

思想:按位分析,从个位开始一位位分析,最后计算每个位中K出现次数的和

对个位进行分析:

例1:n=723, k=1   即((n%10)>k)

个位:个位出现1的情况为001,011,021........711,721

出现的个数为:73次  即n/10+1

例2: n=723,k=3  即((n%10)==k)

个位:个位出现3的情况为003,013,023........713,723

出现的个数为:73次  即n/10+1
例3:n=723,k=5  即(n%10)

个位:个位出现5的情况为005,015,025........715

出现的个数为:72次  即n/10

对十位进行分析:
例1:n=723,k=1 即(((n/10)%10)>k)
十位:十位出现1的情况为010~019,110~029.........610~619,710~719
出现的个数为:80次 即(n/10/10+1)*10
例2:n=723,k=2 (((n/10)%10)==k)
十位:十位出现2的情况为020~029,020~029.........620~629,720~723
出现的次数是7*10+4=74 即(n/10/10)*10+n%10+1
例3:n=723,k=3 即(((n/10)%10)十位:十位出现1的情况为030~039,130~139........630~639
出现的次数是7*10=70次 即(n/10/10)*10

百位和十位的分析方法一样,总之要得到哪个位上K出现的次数就要先得到该位上数的大小与k比较
所以我们可以令n=n/10,一位一位的算,但是会发现在对十位分析的例2中需要得到该位的更低位的值,所以我们可以用P=n
比如在十位的分析中我们先令p=n,然后p=p/10;此时p/10就是比十位更高位的值,如百位千位等,而此时n%10就是比十位更低位的值,即个位值,这个细讲比较困难,要自己去体会,多看看例子就明白了,然后结合代码看
最终得到的公式就是:
if(p%10>k)  singlecount=(p/10+1)*(10^num);
if(p%10==k) singlecount=(p/10)*(10^num)+n%(10^num)+1;
if(p%10
其中num是表示位的位置,如果是十位那么十位上出现一个K就代表着出现10次,num=0表示个位,num=1表示十位,十位上出现一次k,就要加10^1,百位加10^2
singlecount表示单个位上K的出现次数


最后还有两种情况没考虑到第一种是K为0的情况,最高位上是不能出现0的,所以不能那么算,0是逢10便有,所以 count=n/10+1;
第二种是n=0  此时count=0
class Solution {
    /*
     * param k : As description.
     * param n : As description.
     * return: An integer denote the count of digit k in 1..n
     */
    public int digitCounts(int k, int n) {
       int count=0,singlecount=0;
		int p=n;
		int num=0;//表示处理数字的位数 num=0表示处理个位 1表示十位等
		if(k==0) return (n/10)+1;
		if(n==0) return 0;
		while(p!=0){
			if((p%10)>k) singlecount=(int) ((p/10+1)*(Math.pow(10, (double)num)));
			if((p%10)==k) singlecount=(int) ((p/10)*(Math.pow(10, (double)num))+(n%((Math.pow(10, (double)num))))+1);
			if((p%10)



你可能感兴趣的:(编程训练)