LeetCode 204. Count Primes
Woodyiiiiiii opened this issue · comments
Count the number of prime numbers less than a non-negative number, 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
Constraints:
0 <= n <= 5 * 106
对于 判断素数(prime number) 问题,一般使用的是素数筛法,第一种是常用的 埃拉托色尼筛法,时间复杂度是O(nlognlogn):
for (int i = 2; i < Math.sqrt(n); ++i) {
if (!np[i]) {
for (int j = i * i; j < n; j += i) {
np[j] = true;
}
}
}
for (int i = 2; i < n; ++i) {
if (!np[i]) {
++ans;
}
}
return ans;
}
}
但该方法有个问题,一些数会被重复判定,比如12 = 2 * 6 = 3 * 4,所以引出如下欧拉筛法,也叫线性筛。
第二种是O(n)的 欧拉筛法,维护一个质数表(primes),每次用素数乘以质数表的数,排除那些非素数,并且循环是需要遍历所有数,而不是到Math.sqrt(n)为止。该筛法的核心**是让每一个合数被其最小质因数筛到。
//欧拉筛,素数筛
class Solution {
public int countPrimes(int n) {
int ans = 0;
boolean[] np = new boolean[n + 1];
List<Integer> primes = new LinkedList<>();
for (int i = 2; i < n; ++i) {
if (!np[i]) {
primes.add(i);
}
for (int p : primes) {
if (p * i > n) {
break;
}
np[p * i] = true;
if (i % p == 0) {
break;
}
}
}
for (int i = 2; i < n; ++i) {
if (!np[i]) {
++ans;
}
}
return ans;
}
}
参考资料: