1. 程式人生 > >【Java】 劍指offer(43) 從1到n整數中1出現的次數 《劍指Offer》Java實現合集 《劍指Offer》Java實現合集

【Java】 劍指offer(43) 從1到n整數中1出現的次數 《劍指Offer》Java實現合集 《劍指Offer》Java實現合集

本文參考自《劍指offer》一書,程式碼採用Java語言。

更多:《劍指Offer》Java實現合集  

題目 

 輸入一個整數n,求從1到n這n個整數的十進位制表示中1出現的次數。例如輸入12,從1到12這些整數中包含1 的數字有1,10,11和12,1一共出現了5次。

思路

  如果是從頭到尾遍歷(n次),對每一個數字都計算其1的個數(lgn次),則時間複雜度為O(nlogn),運算效率太低。因此必須總結規律,提高效率。

  總結規律如下(思路比《劍指OFFER》一書簡單):

  對於整數n,我們將這個整數分為三部分:當前位數字cur,更高位數字high,更低位數字low,如:對於n=21034,當位數是十位時,cur=3,high=210,low=4。

  我們從個位到最高位 依次計算每個位置出現1的次數:

  1)當前位的數字等於0時,例如n=21034,在百位上的數字cur=0,百位上是1的情況有:00100~00199,01100~01199,……,20100~20199。一共有21*100種情況,即high*100;

  2)當前位的數字等於1時,例如n=21034,在千位上的數字cur=1,千位上是1的情況有:01000~01999,11000~11999,21000~21034。一共有2*1000+(34+1)種情況,即high*1000+(low+1)。

  3)當前位的數字大於1時,例如n=21034,在十位上的數字cur=3,十位上是1的情況有:00010~00019,……,21010~21019。一共有(210+1)*10種情況,即(high+1)*10。

  這個方法只需要遍歷每個位數,對於整數n,其位數一共有lgn個,所以時間複雜度為O(logn)

 

測試算例 

  1.功能測試(3,45,180等)

  2.邊界值測試(0,1等)

  3.效能測試(輸入較大的數字,如1000000等)

Java程式碼

//題目:輸入一個整數n,求從1到n這n個整數的十進位制表示中1出現的次數。例如
//輸入12,從1到12這些整數中包含1 的數字有1,10,11和12,1一共出現了5次。

public class NumberOf1 {
    public int NumberOf1Between1AndN_Solution(int n) {
        int count=0;
        for(int i=1;i<=n;i*=10){  //i代表位數
            int high=n/(i*10); //更高位數字
            int low=(n%i);  //更低位數字
            int cur=(n/i)%10;  //當前位數字
            if(cur==0){
                count+=high*i;
            }else if(cur==1){
                count+=high*i+(low+1);
            }else{
                count+=(high+1)*i;
            }
        }
        return count;
    }
}

  

收穫

  1.找規律要耐心!欲速則不達。

  2.學會提取不同位置的數字,以及更高、更低位置的數字;學會遍歷每個位數的迴圈。

 

更多:《劍指Offer》Java實現合集