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的质数的个数
![[中等] 204. 计数质数 - 图1](/uploads/projects/liangduo-rjrcs@ggu4wq/98e1c0298d72b8e2e94fece98dd226d3.gif)
class Solution {public:int countPrimes(int n) {if(n < 2)return 0;// 1. 数组 isPrime: isPrime[i] 代表 i 是否为质数。初始化都为 truevector<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, ... 都不可能是质数,标为 falseif(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% 的用户
