《劍指office》整數中1出現的次數


題目描述
求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。
 解題思路
考慮將n的十進制的每一位單獨拿出討論,每一位的值記爲weight。
1) 個位
從1到n,每增加1,weight就會加1,當weight加到9時,再加1又會回到0重新開始。那麼weight從0-9的這種週期會出現多少次呢?這取決於n的高位是多少,看圖: 

以534爲例,在從1增長到n的過程中,534的個位從0-9變化了53次,記爲round。每一輪變化中,1在個位出現一次,所以一共出現了53次。 
再來看weight的值。weight爲4,大於0,說明第54輪變化是從0-4,1又出現了1次。我們記1出現的次數爲count,所以: 
count = round+1 = 53 + 1 = 54

如果此時weight爲0(n=530),說明第54輪到0就停止了,那麼: 
count = round = 53
2) 十位
對於10位來說,其0-9週期的出現次數與個位的統計方式是相同的,見圖: 

不同點在於:從1到n,每增加10,十位的weight纔會增加1,所以,一輪0-9週期內,1會出現10次。即rount*10。 
再來看weight的值。當此時weight爲3,大於1,說明第6輪出現了10次1,則: 
count = round*10+10 = 5*10+10 = 60

如果此時weight的值等於0(n=504),說明第6輪到0就停止了,所以: 
count = round*10+10 = 5*10 = 50

如果此時weight的值等於1(n=514),那麼第6輪中1出現了多少次呢?很明顯,這與個位數的值有關,個位數爲k,第6輪中1就出現了k+1次(0-k)。我們記個位數爲former,則: 
count = round*10+former +1= 5*10+4 = 55
3) 更高位
更高位的計算方式其實與十位是一致的,不再闡述。
4) 總結
將n的各個位分爲兩類:個位與其它位。 
對個位來說:
  • 若個位大於0,1出現的次數爲round*1+1
  • 若個位等於0,1出現的次數爲round*1
對其它位來說,記每一位的權值爲base,位值爲weight,該位之前的數是former,舉例如圖: 


則:
  • 若weight爲0,則1出現次數爲round*base
  • 若weight爲1,則1出現次數爲round*base+former+1
  • 若weight大於1,則1出現次數爲rount*base+base
比如:
  • 534 = (個位1出現次數)+(十位1出現次數)+(百位1出現次數)=(53*1+1)+(5*10+10)+(0*100+100)= 214
  • 530 = (53*1)+(5*10+10)+(0*100+100) = 213
  • 504 = (50*1+1)+(5*10)+(0*100+100) = 201
  • 514 = (51*1+1)+(5*10+4+1)+(0*100+100) = 207
  • 10 = (1*1)+(0*10+0+1) = 2
代碼:
public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int temp1 = 1;
        int temp2 = n,sum = 0,temp3=0;
        if(n==1){
            return 1;
        }
        while(temp2!=0){
            int x = temp2%10;
            int y = temp2/10;
            if(x>1){
                sum = sum + y*temp1 + temp1;
            }else if(x==0){
                sum = sum + y*temp1;
            }
            else{
                sum = sum + y*temp1 + temp3 + 1;
            }
            temp1 = temp1 * 10;
            temp3 = n % temp1;
            temp2 = temp2 / 10;
        }
        return sum;
    }
}


發佈了37 篇原創文章 · 獲贊 80 · 訪問量 4009
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章