python 2出現的次數

2021-10-10 20:35:41 字數 3996 閱讀 8383

編寫乙個方法,計算從 0 到 n (含 n) 中數字 2 出現的次數。

示例:輸入:

25輸出:

9解釋:(2

,12,20

,21,22

,23,24

,25)(注意 22 應該算作兩次)

n <=10^

9

一、dp方法

第i位是1:

dp[3] = 當第3位是0,1-2位取00-99時2的次數 + 當第3位是1, 1-2位取00~78時2的次數

dp[3] = numberof2sinrange(99) + dp[2]

numberof2sinrange(178) = numberof2sinrange(99) + numberof2sinrange(78)

第i位是2:

dp[3] = 第3位取0-1,1-2位取00-99時2的次數 + 第3位是2,1-2位取00-33時2在1-2位出現的次數 + 第3位是2,1-2位取00~33時2在第3位出現的次數

dp[3] = 2 *numberof2sinrange(99) + dp[2] + 33 + 1

numberof2sinrange(233) = 2 * numberof2sinrange(99) + numberof2sinrange(33) + 33 + 1

第i位大於2:

dp[3] = 第3位取0-3,1-2位取00-99時2出現在1-2位的次數 + 第3位取4,1-2位取00-78時2的次數 + 第3位取2,1-2位取00-99時2出現在第3位的次數

dp[3] = 4 * numberof2sinrange(99) + dp[2] + 100

總結:dp[i]與dp[i-1]的關係,假設n的第i位的值為k

dp[i] = k * numberof2sinrange(99…9) + dp[i-1] + +

class

solution

:def

numberof2sinrange

(self, n:

int)

->

int:

if n ==0:

return

0 digit =

int(math.log(n))+

1 dp =[[

0,0]

for _ in

range

(digit +1)

]#dp[i][0] = numberof2sinrange(n % pow(10, i)) 儲存0~n的1-i位組成的數包含2的個數

#dp[i][1] = numberof2sinrange(99..9) 儲存i位均為9包含2的個數

dp[1]

[0]=

1if n %

10>=

2else

0 dp[1]

[1]=

1for i in

range(2

,digit+1)

: k = n //

(int

(math.

pow(

10, i-1)

))%10

dp[i][0

]= k * dp[i-1]

[1]+ dp[i-1]

[0]if k ==2:

dp[i][0

]+= n %

(int

(math.

pow(

10, i-1)

))+1

elif k >2:

dp[i][0

]+=int(math.

pow(

10, i-1)

) dp[i][1

]=10* dp[i-1]

[1]+

int(math.

pow(

10, i-1)

)return dp[digit][0

]

二、切片法

分別統計每位(個、十、百、千位等等)出現2的次數:

百位大於2(12313):

要想百位出現2,由於當前百位是3,那麼最終的次數只依賴於更高位

00200-00299 100個數

01200-01299 100個數

…12200-12299 100個數

所有百位出現2的總個數為從0到12 共13個100,即13*100=1300

百位小於2(12113):

要想百位出現2,由於當前位是1,那麼最終的次數同樣依賴於更高位,只不過會比上面的情況少最後一種

00200-00299 100個數

01200-01299 100個數

…11200-11299 100個數

那麼加起來就是(12)10**len(『13』)

百位2等於2(12213):

首先我們取前三位不大於121的所有情況,就是上面的結論2

00200-00299 100個數

01200-01299 100個數

…11200-11299 100個數,還是12100個數,其次取前三位是122的情況:

12200-12213 這一共是14個數。

class

solution

:def

numberof2sinrange

(self, n:

int)

->

int:

s =str(n)

cnt =

0for i in

range

(len

(s))

: current =

int(s[i]

) high =

0if s[

:i]==

''else

int(s[

:i])

low =

0if s[i+1:

]==''else

int(s[i+1:

])if current >2:

cnt +=

(high +1)

*(10**

len(s[i+1:

]))elif current <2:

cnt +=

(high)*(

10**

len(s[i+1:

]))else

: cnt +=

(high)*(

10**

len(s[i+1:

]))+ low +

1return cnt

使用數學方法表達時:

給定數字從個位開始向上分析

例如n=324時

i a b res

1 324 0 (324+7)/101 + 0 = 33

10 32 4 (32+7)/1010 + 5 = 35

100 3 24 (3+7)/10*100 = 100

「+7」是為特殊情況設計,當取值為0,1,2時不會產生進製,大於2時允許產生進製。

class

solution

:def

numberof2sinrange

(self, n:

int)

->

int:

if n <=1:

return

0if n <=11:

return

1 a, b, res =0,

0,0 i =

1while i <= n:

a = n//i

b = n%i

res +=

(a +7)

//10

*i +

(a%10==2

)*(b+1

) i *=

10return res

整數中1出現的次數

針對牛客網試題作個記錄 問題 整數中1出現的次數 從1到n整數中1出現的次數 求出1 13的整數中1出現的次數,並算出100 1300的整數中1出現的次數?為此他特別數了一下1 13中包含1的數字有1 10 11 12 13因此共出現6次,但是對於後面問題他就沒轍了。acmer希望你們幫幫他,並把問...

整數中1出現的次數

乙個更好的辦法是利用數學公式直接計算出最終的結果,該方法是依次求出數字 x 在個位 十位 百位等等出現的次數,再相加得到最終結果。這裡的 x 1,9 x 1,9 因為 x 0 x 0不符合下列規律,需要單獨計算。首先要知道以下的規律 依此類推,從 1 至 10 i 10i 在它們的左數第二位 右數第...

整數中1出現的次數

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