题目
给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。
示例 1:
输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
示例 2:输入:n = 0
输出:0
示例 3:输入:n = 1
输出:0提示:
0 <= n <= 5 * 10^6
思路
埃氏筛,很赞的算法,相比于暴力枚举已经优化了很多。
基本思路是,从开始,对于每个质数,将其的倍数标记为合数。这里有几个细节:
- 需要标记的是每个质数的倍数,而不是自然数的倍数,因为合数的倍数一定在之前标记过了。比如
的倍数全部标记过后,
和
的倍数就一定标记过了。
- 每次只需从自身的平方
开始标记,比如对于
标记了
,到了
的时候,
就已经标记过了,只需从
开始。
可能溢出,要转为long
代码
class Solution {
public int countPrimes(int n) {
if (n == 0) return 0;
// isComposite[i]表示i是否为合数
boolean[] isComposite = new boolean[n + 1];
int ans = 0;
for (int i = 2; i < n; i++) {
if (!isComposite[i]) {
ans++;
if ((long) i * i >= n) {
continue;
}
for (int j = i * i; j < n; j += i) {
isComposite[j] = true;
}
}
}
return ans;
}
}