每日一題20201203(204. 計數質數)
阿新 • • 發佈:2020-12-03
204. 計數質數
思路
-
列舉
一般咱們用來判斷一個數比如說23是否是質數,我們可以用23除以[2, 23)裡面的數字,一旦有數字大於1,該數字肯定就不是質數。
但是每次除以那麼多數字,其實可以簡化。
想想一下,判斷x是否是y的因數(也就是x是否能被y整除)
如果x是y的因素,那麼y ÷ x肯定也是y的因數,所以其實只要計算[2, min(y/x, y)]是否能被y整除就行。
那麼什麼時候y/x最小呢
引用一下題解,感覺比我解釋的好:
但是此方法會超時
// 超時警告 func isPrime(x int) bool { for i := 2; i*i <= x; i++ { if x%i == 0 { return false } } return true } func countPrimes(n int) (cnt int) { for i := 2; i < n; i++ { if isPrime(i) { cnt++ } } return }
-
埃氏篩
簡單的說就是,如果x是質數,那麼2x 3x 4x....這些一定不是質數
那麼從2開始我們就可以找出2的2倍,3倍,排除這些非質數,一直遍歷,看數組裡還有哪些質數,數量+1,返回總數即可
所以可以寫出如下程式碼:
func countPrimes(n int) (cnt int) { // 建立一個bool陣列,裡面存放第N個數是否是質數 // 初始化,使得每個數都是質數 isPrime := make([]bool, n) for i := range isPrime { isPrime[i] = true } // 從2開始 2是質數,把數組裡2的倍數都刷為素數 for i := 2; i < n; i++ { if isPrime[i] { cnt++ for j := 2 * i; j < n; j += i { isPrime[j] = false } } } return }
class Solution: def countPrimes(self, n: int) -> int: ans = 0 result = [True for i in range(n)] for i in range(2, n): if result[i]: ans += 1 j = 2 * i while j < n: result[j] = False j += i return ans