Medium
题目描述
给你一个整数 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
提示:
- 检查 [1, n - 1] 范围内的所有整数效率不高。考虑一个更好的方法。
- 由于大多数数字都不是质数,我们需要一种快速的方法来排除非质数整数。
- 使用埃拉托斯特尼筛法。
解题思路
这是一个经典的数论问题,有多种解法:
方法一:暴力枚举(不推荐) 对每个数字从2开始检查是否为质数,时间复杂度为O(n²),在n较大时会超时。
方法二:优化的暴力枚举 对每个数字只需检查到√n即可判断是否为质数,时间复杂度为O(n√n),仍然较慢。
方法三:埃拉托斯特尼筛法(推荐) 这是最经典也是最高效的解法。基本思想是:
- 创建一个布尔数组标记每个数是否为质数,初始都设为true
- 从2开始,将每个质数的所有倍数标记为非质数
- 优化:只需要筛选到√n,因为大于√n的质数的最小倍数已经被较小的质数筛掉了
- 再次优化:从i²开始筛选,因为i×2, i×3, …, i×(i-1)都已经被更小的质数筛掉了
这个算法的时间复杂度接近O(n log log n),空间复杂度O(n),是解决这类问题的标准方法。
代码实现
class Solution {
public:
int countPrimes(int n) {
if (n <= 2) return 0;
vector<bool> isPrime(n, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i < n; i++) {
if (isPrime[i]) {
for (int j = i * i; j < n; j += i) {
isPrime[j] = false;
}
}
}
int count = 0;
for (int i = 2; i < n; i++) {
if (isPrime[i]) count++;
}
return count;
}
};
class Solution:
def countPrimes(self, n: int) -> int:
if n <= 2:
return 0
is_prime = [True] * n
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
for j in range(i * i, n, i):
is_prime[j] = False
return sum(is_prime)
public class Solution {
public int CountPrimes(int n) {
if (n <= 2) return 0;
bool[] isPrime = new bool[n];
Array.Fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i < n; i++) {
if (isPrime[i]) {
for (int j = i * i; j < n; j += i) {
isPrime[j] = false;
}
}
}
int count = 0;
for (int i = 2; i < n; i++) {
if (isPrime[i]) count++;
}
return count;
}
}
var countPrimes = function(n) {
if (n <= 2) return 0;
const isPrime = new Array(n).fill(true);
isPrime[0] = isPrime[1] = false;
for (let i = 2; i * i < n; i++) {
if (isPrime[i]) {
for (let j = i * i; j < n; j += i) {
isPrime[j] = false;
}
}
}
let count = 0;
for (let i = 2; i < n; i++) {
if (isPrime[i]) count++;
}
return count;
};
复杂度分析
| 复杂度 | 大小 |
|---|---|
| 时间复杂度 | O(n log log n) |
| 空间复杂度 | O(n) |
相关题目
. Ugly Number (Easy)
. Ugly Number II (Medium)
. Perfect Squares (Medium)
. Number of Common Factors (Easy)
. Prime Pairs With Target Sum (Medium)