劍指 offer 43. 1~n整數中1出現的次數
輸入乙個整數 n ,求1~n這n個整數的十進位制表示中1出現的次數。
例如,輸入12,1~12這些整數中包含1 的數字有1、10、11和12,1一共出現了5次。
首先看到這道題,我們會想到遍歷從1到n,然後計算每乙個數中1的個數,然後相加即可。
這樣的時間複雜度是o(nlogn),(從1遍歷到n,時間複雜度為o(n),計算每乙個數中1的個數,時間複雜度為o(logn),所以總體的時間複雜度為o(nlogn))。
這樣我們能輕易的寫出**
class
solution
n=n/10;
}return sum;
}int
countdigitone
(int n)
return sum;}}
;
由於上面的**的時間複雜度為o(nlogn),如果對時間要求比較嚴格的話,這種演算法是肯定沒法通過了。所以我們就要想出乙個新的複雜度比較低的演算法。下面我向大家展示乙個時間複雜度為o(logn)的演算法。
我們可以根據n的每一位數,求出從1到n中1的個數。
我們可以把n分為三部分,high,cur,low;cur表示當前考慮的位數,high表示cur前面的高位,low表示cur後面的低位。dig表示該位數代表是數字大小,比如十位dig=10,百位dig=100(下面我以十位為例)
例:求出從1到2304中1的位數。(考慮從1 到2304中所有數中十位為1的個數)
0010~0019 (10個)
0110~0119 (10個)
…2210~2219 (10個)
十位中總共有 (2310個1)
所以當cur=0時,從1到n中該位為1的個數有 highdig個
例:求出從1到2314中1的位數。(考慮從1 到2314中所有數中十位為1的個數)
0010~0019 (10個)
0110~0119 (10個)
…2210~2219 (10個)
2310~2314 (5個)
十位中總共有 (2310+4+1個1)
所以當cur=0時,從1到n中該位為1的個數有 highdig+low+1個
例:求出從1到23x4中1的位數。(考慮從1 到23x4中所有數中十位為1的個數,x表示大於1小於10的正整數)
0010~0019 (10個)
0110~0119 (10個)
…2210~2219 (10個)
2310~2319 (10個)
十位中總共有 (24*10個1)
所以當cur=0時,從1到n中該位為1的個數有 (high+1)*dig個
由上面的例子我們可以得出,要想求出從1到n中所有數中1的個數,我們只需考慮n的每一位數,及其對應的high、low,cur和dig
由此我們可以寫成以下**
class
solution
return res;}}
;
這樣我們就能寫成計算從1到n中所有數中1的個數這道題的時間複雜度為o(logn)的演算法啦.
劍指offer 43 1 n整數中 1出現的次數
求出1 13的整數中1出現的次數,並算出100 1300的整數中1出現的次數?為此他特別數了一下1 13中包含1的數字有1 10 11 12 13因此共出現6次,但是對於後面問題他就沒轍了。acmer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。思路1 算出數字n...
劍指Offer 43 1 n整數中1出現的次數
輸入乙個整數n,求1 n這n個整數的十進位制表示中1出現的次數。例 輸入12,1 12這些整數中包含1的數字有1 10 11和12,1一共出現了5次。遍歷1 n,每個數字轉換成字串計數1的個數。時間複雜度 o nlogn 空間複雜度 o 1 將1 n分段,分別處理。num n1n 2.n inum ...
劍指offer43 1 n整數中1出現的次數
1 n整數中1出現的次數 這個題目暴力解決貌似可以通過,但時間複雜度太大了。比如數字21345,可以把他分為2段,1 1345 1346 21345 先看1346 21345,因為最高位是2,大於1,因此,只看最高位的話,1出現的次數就是10000 19999,即10000次 看低位,我們發現包括1...