43 1 n 整數中 1 出現的次數

2021-10-21 13:41:42 字數 2833 閱讀 9678

輸入乙個整數n,求1~nn個整數的十進位制表示中1出現的次數。

例如,輸入121~12這些整數中包含1的數字有1、10、1112,1一共出現了5次。

示例 1:

輸入:n = 12

輸出:5

示例 2:

輸入:n = 13

輸出:6

限制:1 <= n < 2^31注意:本題與主站 233 題相同:

最直觀的做法,就是累加1 ~ n中每個整數出現1的次數,我們可以通過對10求餘數判斷整數的個位數字是不是1,如果這個數字大於10,則除以10之後再判斷個位數字是不是1

遺憾的是tle了,在上述思路中,我們對每個數字都要做除法和求餘運算,以求出該數字中1出現的次數。而我們知道,對於乙個數字n,它有o(l

ogn)

o(logn)

o(logn

)位,如100有log

10100+1

=3log_100 +1=3

log10​

100+

1=3 位,即求乙個數n有多少位的時間複雜度是o(l

ogn)

o(logn)

o(logn

)的,又我們需要求n個數字,即n次,那麼總時間複雜度就是o(n

logn

)o(nlogn)

o(nlog

n),當輸入的n非常大的時候,需要大量的計算,運算效率不高,導致超時了。

我們假設n = abcdef,其中等號右邊a1~9中的某個數字,其餘的可為0~9中某個數字,我們需要做的就是統計每個位上,如個位、十位、百位…上能出現1的次數的總和。

假設求c位置為1的個數:

此時c左邊和右邊的值分別為lval = ab, rval = def, 而t = 1000,表示c的位置是千位的位置

此時則有如下兩種情況:

lval[0, ab-1];右邊可以從0取到999,也就是此時c位置可以出現10001,我們用t表示,因為t就是1000, 此時res += lval * t;

lvalab

舉例 :

假如n = 123456

假設當前計算千位上出現1的個數,在千位上有_ _x_ _ _x的左邊有12,右邊有456

當左邊是[0,11]時,千位上可以為1,且千位右邊的三位可以是0~999,即千位上的數字我們固定為1,左邊是[0-11]的任意乙個數字時,右邊可以是0~999,共1000個選擇,所以千位是1的個數是12 * 1000如果左邊是12

class

solution

for(

int i = numbers.

size()

-1; i >=

0; i--

)// 左邊

res += lval * t;

// 右邊

面試題43 1 n整數中1出現的次數

輸入乙個整數n,求1 n這n個整數的十進位制表示中1出現的次數。例如,輸入12,1 12這些整數中包含1的數字有1 10 11和12,1一共出現了5次。對於乙個數,每次對10取餘判斷最低位是不是1,就可以得到這個數中1的數量,從1遍歷到n,每個數都這麼做,就可以得到1的總數量了。看劍指offer上的...

面試題43 1 n整數中1出現的次數

求出1 13的整數中1出現的次數,並算出100 1300的整數中1出現的次數?為此他特別數了一下1 13中包含1的數字有1 10 11 12 13因此共出現6次,但是對於後面問題他就沒轍了。acmer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數 從1 到 n 中1...

面試題43 1 n整數中1出現的次數

輸入乙個整數 n 求1 n這n個整數的十進位制表示中1出現的次數。例如,輸入12,1 12這些整數中包含1 的數字有1 10 11和12,1一共出現了5次。示例 1 輸入 n 12 輸出 5 示例 2 輸入 n 13 輸出 6 限制 1 n 2 31 思路 遞迴。將數字分為最高位和後幾位。當數字由1...