算法学习之整数中1出现的次数(从1到n整数中1出现的次数)

题目描述

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

那种简单的嵌套双遍历这里就不讲了,说一下另一种思路,使用归纳法总结套路公式老解决。

1、个位1出现的次数:

个位来说1出现的次数会每隔10出现一次,1、11、21、31...所以个位1出现的次数为n/10,但是输入的数字可能不是像1、11这种理想的数字可能会多出一部分,如题目所述的13,这时候如果多出来了11~13可能就需要单独算出来,然后累加到前面的结果。所以有:

k=n%10;

count = n/10+ if(k!=0)1 else 0 

2、十位1出现的次数:

十位为每隔100位数出现一次,10,110,210...所以十位1出现的次数为n/100,同上,如果出现多出的情况,则需要累加多余的符合条条件的结果,得出:

k=n%100;

count = (n/100)*10+if(k>19) 10 else if(k<10) 0 else k -10+1

3、百位1出现的次数:

百位每隔1000位数出现一次,100,1100,2100...所以百位1出现的次数n/1000,跟个位相同,出现多出的情况,则累加:

k=n%1000;

count = (n/1000)*100+if(k>199) 100 else if(k<100) 0 else k -100+1

通过上边我们可以总结出:

i范围为10~log10(n)

k=n%(10*i)

count = (n/(10*i))*i+if(k>10*i-1) i else if(k<0)0 else k-i+1

最后使用Math的min与max替换if else的操作

 

import java.util.*;
public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
          if(n<=0)return 0;
          int count = 0;
          for(long i =1;i<=n;i*=10){
              long tem = i*10;
              count +=(n/tem)*i + Math.min(Math.max(n%tem-i+1,0),i);// 保证k-i+1在[0,1]内,其实就是用Math替换掉了if和else if
          }
        return count;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章