Leetcode刷题笔记 204. 计数质数

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

解法

  1. 最简单的是就是遍历枚举 找到没个符合条件的 其中的优化可以是 i*i<=n 能减少一半的计算
  2. 之后是埃氏筛 类似于打表 如果是质数 质数的倍数都是非质数标记 能达到nlogn
  3. 最后是线性筛 不是质数打表 而是每个数 * 质数表中的数
  4. 重要的是结束条件 数%质数==0 为的是确保和数只被最小的质因数筛去 如15 可能被3筛去 或者 5筛去

代码

#include 
#include 
#include 
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 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的一天哦!

你可能感兴趣的:(leetcode,leetcode)