204. 计数质数
时间:2020年12月3日
知识点:打表、埃氏筛、线性筛
题目链接:https://leetcode-cn.com/problems/count-primes/
题目
统计所有小于非负整数 n 的质数的数量。
示例 1:
输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
示例 2:
输入:n = 0
输出:0
示例 3:
输入:n = 1
输出:0
提示:
- 0 <= n <= 5 * 106
解法:
- 最简单的是就是遍历枚举 找到没个符合条件的 其中的优化可以是 i*i<=n 能减少一半的计算
- 之后是埃氏筛 类似于打表 如果是质数 质数的倍数都是非质数标记 能达到nlogn
- 最后是线性筛 不是质数打表 而是每个数 * 质数表中的数
- 重要的是结束条件 数%质数==0 为的是确保和数只被最小的质因数筛去 如15 可能被3筛去 或者 5筛去
代码
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
// 线性筛 时间复杂度 O(n) 空间(n)
class Solution {
public:
int countPrimes(int n){
vector<int> primes;
vector<int> isPrime(n, 1);
for (int i = 2; i < n; i++){
if (isPrime[i]) {
primes.push_back(i);
}
for (int j = 0; j < primes.size() && i * primes[j] < n; j++){
isPrime[i * primes[j]] = 0;
if (i % primes[j] == 0){
break;
}
}
}
return primes.size();
}
};
/* 埃氏筛 时间复杂度 O(nlogn) 空间O(n)
class Solution {
public:
int countPrimes(int n){
vector<int> isPrime(n,1);
int ans = 0;
for (int i = 2; i < n; i++){
if (isPrime[i]){
ans += 1;
for (int j = i * i; j < n; j += i)
isPrime[j] = 0;
}
}
return ans;
}
};
枚举 时间复杂度 O(n√n) 空间O(1)
class Solution {
public:
bool isPrime(int x){
for (int i = 2; i * i <= x; i++){
if (x % i == 0){
return false;
}
}
return true;
}
int countPrimes(int n){
int ans = 0;
for (int i = 2; i < n; i++){
ans += isPrime(i);
}
return ans;
}
};
*/
int main()
{
int n = 20;
Solution s;
cout<<s.countPrimes(n)<<endl;
return 0;
}
今天也是爱zz的一天哦!