204 計數質數

2021-09-27 11:42:57 字數 2019 閱讀 1845

統計所有小於非負整數 n 的質數的數量。

示例:

輸入: 10

輸出: 4

解釋: 小於 10 的質數一共有 4 個, 它們是 2, 3, 5, 7 。

這個題目思路很簡單,但是可能效率不高,裡面有一些小trick需要注意,所以在這裡記錄一下優化過程。

思路1: 逐個判斷每個數是否質數,(超時)

class solution:

def countprimes(self, n: int) -> int:

def isprime(val):

if val <= 1:

return false

for i in range(2, int(math.sqrt(val)) + 1):

if val % i == 0:

return false

return true

count = 0

for i in range(n):

if isprime(i):

count += 1

return count

思路2:厄拉多塞篩法

實現上的小細節: 可以想到的是i從2-n進行遍歷,但怎麼判斷i是否被標記呢?

被標記的放到list或者dict,每次遇到i進行查詢

或者 建立乙個size=n陣列進行標記

查詢操作太慢, 實現會超時,這裡採用思路2,

1760 ms 25.3 mb, 超過7.20%

class solution:

def countprimes(self, n: int) ->int:

nums = [0] * n

res = 0

for i in range(2, n):

if nums[i] == 0:

mul = 2

res += 1

while mul * i < n:

nums[mul * i] += 1

mul += 1

return res

再進行一些小優化, while迴圈換成陣列操作

500 ms, 37.2 mb, 超過46.82%

class solution:

def countprimes(self, n: int) ->int:

nums = [0] * n

res = 0

for i in range(2, n):

if nums[i] == 0:

res += 1

nums[2*i : n : i] = [1]*len(nums[2*i : n : i])

return res

繼續優化, 主要是有乙個這樣的觀察:

假如當遍歷到5的時候,我們會對 5 * 2, 5 * 3, 5 * 4, 5 * 5, … 進行標記,但其實發現 5 * 2, 5 * 3, 5 * 4, 這些在之前已經被標記了,所以直接從 5 * 5進行標記, 即對於i * i開始遍歷; 另外, 當i超過sqrt(n)是, i * i就會超過 n,這時就不會改變標記。 所以只需要遍歷到 sqrt(n)。質數的個數就是 n - 被標記的個數。

204 ms, 37.1 mb, 超過77.81%

class solution:

def countprimes(self, n: int) ->int:

if n < 2:

return 0

nums = [0] * n

nums[1] = nums[0] = 1

for i in range(2, int(math.sqrt(n)) + 1):

if nums[i] == 0:

nums[i*i : n : i] = [1]*len(nums[i*i : n : i])

return n - sum(nums)

204 計數質數

統計所有小於非負整數 n 的質數的數量。示例 輸入 10 輸出 4 解釋 小於 10 的質數一共有 4 個,它們是 2,3,5,7 判斷質數的常規解法 如判斷n是否為質數,只需要判斷n是否能整除2 int sqrt n 厄拉多塞篩法 比如說求20以內質數的個數,首先0,1不是質數.2是第乙個質數,然...

204 計數質數

統計所有小於非負整數 n 的質數的數量。示例 輸入 10 輸出 4 解釋 小於 10 的質數一共有 4 個,它們是 2,3,5,7 埃拉託色尼篩選法,迴圈中置對應值的倍數為0,最後統計為1的個數,也就是質數的個數。class solution def countprimes self,n int i...

204 計數質數

題目 尋找 2,n 的質數是很常見的問題,主要有三種方法,現總結如下 列舉法思路簡單,但是要注意這幾點 1 0和1應該要特判,除非在判斷質數時壓根就不讓0,1參與選擇,直接從2開始 2 為了判斷n是否是質數,只需要列舉i 2至i 根號n,但是在程式中應該表現為i i n,素數條件如果從i i x改為...