0204. Count Primes - chasel2361/leetcode GitHub Wiki
Given an integer n, return the number of prime numbers that are strictly less than n.
Example 1:
Input: n = 10
Output: 4
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
Example 2:
Input: n = 0
Output: 0
Example 3:
Input: n = 1
Output: 0
這題要解不算太難,只要從2到n檢查是否為質數即可,一開始寫出來的程式碼如下:
class Solution:
def countPrimes(self, n: int) -> int:
if n <= 2: return 0
cnt = 0
for n_ptr in range(2, n):
ptr_basis = round(n_ptr**0.5)
is_prime = True
for i in range(2, ptr_basis + 1):
if n_ptr % i == 0:
is_prime = False
break
if is_prime:
cnt += 1
return cnt
不過這樣寫的問題是算太慢,系統過不了
所以參考了大大的寫法,發現有一個特定方法叫做埃拉托斯特尼篩法(sieve of Eratosthenes)
概念是把所有的數列出來,然後取質數出來,把質數的倍數篩掉,這樣只要篩到最小質數可能發生的數(n**0.5)就可以了
寫出來的程式碼如下:
class Solution:
def countPrimes(self, n: int) -> int:
if n < 3: return 0
primes = [1] * n
primes[0] = primes[1] = 0
for i in range(2, round(n**0.5) + 1):
if primes[i]:
primes[i*i: n: i] = [0] * ((n-1 - i*i) // i + 1)
# n = 11
# i = 2
# (n-1-i*i)//i + 1
# (n-1) # get total # of indicies for n (non-inclusive)
# -i*i # shift to get # of slots in range of interest
# //i # get number of groups
# + 1 # get number of slots
# strikes[2*2:11:2] = [0] * ((11-1-2*2)//2 + 1
# strikes[4:11:2] = [0] * 4
# s[4], s[6], s[8], s10] = 0, 0, 0, 0
return sum(primes)
這樣寫的時間複雜度是O(n), 空間複雜度比較複雜,是O(nloglogn) wiki有提供演算概念圖如下
另外如果用C++寫的話會長成這樣
# include <vector>
class Solution {
public:
int countPrimes(int n) {
if (n < 3) return 0;
vector<bool> seen(n, false);
int ans = 0;
for (int i=2; i < n; i++){
if (seen[i]) continue;
ans++;
for (long mult=(long)i * i; mult < n; mult += i){
seen[mult] = true;
}
}
return ans;
}
};
差別在於C++需要另外用一個變數來儲存質數的個數這樣