算法學習之整數中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;
    }
}

 

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