n的p進製下的數碼之和問題

2021-08-02 23:32:33 字數 2203 閱讀 5573

以前做過一道題(191. number of 1 bits )講的是給定乙個數,求它二進位制下的1的個數。如果是對於乙個數,那麼可以用位運算黑魔法:(對末尾做與1的與運算)

class

solution

(object):

defhammingweight

(self, n):

ans=0

while n:

if n&1==1:

ans+=1

n=n>>1

return ans

今天碰到了乙個高階版的題目,(338. counting bits )題目要求是在o(

n)的時間和空間裡計算出[0

,n] 區間裡所有整數的二進位制下的1的個數(hamming weight - wikipedia)。o(

n)的時間要求是有點小苛刻的,首先遍歷一次[0

,n] 區間裡所有整數就需要o(

n),那麼每次小操作需要在o(

1)內才是可以的,首先想到的是能不能用上面leetcode191的做法來套用呢?不妨分析一下複雜度。

容易看出對於乙個數

n ,這樣的操作(主要是移位操作)時間複雜度是o(

log2

n),那麼利用斯特林公式可以估算區間[0

,n] 區間裡所有整數就需要大約 t(

n)=∑

i=1n

log2

i=lo

g2n!

∼log

2nn=

nlog

2n很遺憾的是並不能直接滿足題目中所要求的o(

n)複雜度,如果消耗一點空間換時間,利用上述的方法還是有機會降到o(

n)的動態規劃的思路:用r

es表示最終的結果,改寫上述方法為乙個一維的遞推式: re

s(n)

=res

([n2

])+n

&1也就是說一直維護這樣的乙個一維陣列,每次都記錄其結果,顯然時間複雜度是o(

n),空間也是o(

n),滿足題目要求。不過這並不是我首先想到的思路,我首先想到的是,直接從n的p進製下的數碼之和角度入手。

class

solution

(object):

defcountbits

(self, num):

ans=[0]

for x in range(1,num+1):

ans+=[ans[x>>1]+(x&1)]

return ans

用sp

(n) 表示n的p進製下的數碼之和,用ap

表示n!

的標準分解中

p 的冪次,即pa

p∤n!

,但pap

+1|n

! 。首先寫出表示式: n=

akpk

+...

+a1p

+a0=

(ak.

..a1

a0)p

容易得出每一項係數的準確公式: ai

=[np

i]−p

[npi

+1]

接著進行一下數學推導:sp

(n)=

∑i=0

kai=

∑i=0

k[np

i]−p

∑i=0

k[np

i+1]

=n+∑

i=1k

[npi

]−p∑

i=0k

[npi

+1]=

n−(p

−1)∑

i=1k

[npi

]−p[

npk+

1]=n

−(p−

1)∑i

=1∞[

npi]

−0=n

−(p−

1)ap

這個推導需要用到勒讓德公式,即n!

中p的冪次為∑∞

i=1[

npi]

,顯然這種辦法主要複雜度回耗在勒讓德公式上,可以觀察到

p 的冪次i達到

logp

n 時候,勒讓德公式後面的每一項均為0,即對於二進位制而言,完成一次勒讓德運算需要o(

log2

n),那麼對於原問題一共需要o(

nlog

2n) 的時間。

N數之和的問題

leetcode n個數之和問題 三數之和 給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 請你找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。示例 給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合...

N數碼解的存在問題

推廣二維n n的棋盤 n n的棋盤,n為奇數時,與八數碼問題相同。n為偶數時,空格每上下移動一次,奇偶性改變。稱空格位置所在的行到目標空格所在的行步數為空格的距離 不計左右距離 若兩個狀態的可相互到達,則有,兩個狀態的逆序奇偶性相同且空格距離為偶數,或者,逆序奇偶性不同且空格距離為奇數數。否則不能。...

關於 n 的p進製下有多少個後導零 的問題

給定數n,求n 的p進製下有多少個後導零。為了簡化問題,p保證為素數。如果用大整數寫法,解法可能會超時。易知,如果乙個數可以另外乙個數被整除,那麼成為這個數的幾倍數的數也可以被整除。利用這個思路,可以推出 如果可以被p整除,那麼這個數的幾倍數的數也可以被整除 即 如果可以使p進製下形成乙個後導0,那...