leetcode:204. 计数质数
题目
给定整数 n
,返回 所有小于非负整数 **n**
的质数的数量 。
示例:
输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
输入:n = 0
输出:0
输入:n = 1
输出:0
解答 & 代码
筛选法:
- 设立一个数组
isPrime
:isPrime[i]
代表i
是否为质数。初始化都为true
- 令
i
从2
开始遍历,直到i < sqrt(n)
。(由于因子的对称性,超过sqrt(n)
后的两个乘数其实和之前重复)- 如果当前数
i
是质数,那么i*2
,i*3
,i*4
, … 都不可能是质数,标为false
。实际上i*2
,i*3
, … 已经被之前i=2
、i=3
的时候标记过了,因此从i*i
开始标记即可
- 如果当前数
- 统计小于
n
的质数的个数
class Solution {
public:
int countPrimes(int n) {
if(n < 2)
return 0;
// 1. 数组 isPrime: isPrime[i] 代表 i 是否为质数。初始化都为 true
vector<bool> isPrime(n, true);
isPrime[0] = false;
isPrime[1] = false;
// 2. 从 2 开始遍历,直到 i < sqrt(n)。(由于因子的对称性,超过 sqrt(n) 后的两个乘数其实和之前重复)
for(int i = 2; i * i < n; ++i)
{
// 如果当前数 i 是质数,那么 i*2, i*3, i*4, ... 都不可能是质数,标为 false
if(isPrime[i])
{
// 实际上 i*2, i*3, ... 已经被之前 i=2、i=3 的时候标记过了,因此从 i*i 开始即可
for(int j = i * i; j < n; j += i)
isPrime[j] = false;
}
}
// 3. 统计小于 n 的质数的个数
int result = 0;
for(int i = 2; i < n; ++i)
{
if(isPrime[i])
++result;
}
return result;
}
};
复杂度分析:
- 时间复杂度
:操作数为 n/2 + n/3 + n/5 + n/7 + … = n × (1/2 + 1/3 + 1/5 + 1/7 + …)
- 空间复杂度 O(n):
执行结果:
执行结果:通过
执行用时:180 ms, 在所有 C++ 提交中击败了 84.40% 的用户
内存消耗:9.9 MB, 在所有 C++ 提交中击败了 94.94% 的用户