题目描述

给定整数 n ,返回所有小于非负整数 n 的质数的数量 。

示例:

输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。

解题思路

概念:

质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

根据概念与题意,自然而然想到从(1, n)的开区间上暴力搜索所有素数(质数)。

判断素数的逻辑从概念上 “除了1和它本身以外不再有其他因数” 上出发,有:

bool isPrime(int x){if(x < 2) return false;for(int i = 2; i < x; ++i){if(x % i == 0) return false;}return true;
}

上述判断算法时间复杂度为O(n),嵌入到外层开区间(1, n)的外层循环内,算法整体时间复杂度直接来到O(n^2),当n很大时直接超时。

枚举改良

isPrime()函数中搜索开区间(1, x)中x的因数,假设ix的因数,那么x / i必定也是x的因数。并且只有当i == sqrt(x)时,有i == x / i,其他情况下,两个因数分布在sqrt(x)左右两侧。

进一步思考,判度素数只需找到一个因数即可返回false,因此我们搜索区间可以缩小到[2, sqrt(x)](查找较小的因数)。整体时间复杂度减小到O(n^1.5)

bool isPrime(int x){if(x < 2) return false;for(int i = 2; i <= sqrt(x); ++i){if(x % i == 0) return false;}return true;
}

埃氏筛

改良后的枚举法时间复杂度还是很大,在C++编译环境下提交依旧会超时,这是因为枚举法终究是忽视区间内数字内在规律的暴力搜索方法。

埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。

仔细分析不难发现这样的规律,假如x是质数,那么x的倍数例如2x、3x、...必为合数 。因此可以这么设计算法,依旧在目标区间(1, n)搜索质数,搜索顺序遵循 由小到大。当搜索到质数时,将其区间内倍数全部标记为合数,由小到大的搜索顺序一定会把下一个质数前的所有合数全部标记。这样就大大减少了判度一个整数是否是质数的次数,进而降低时间复杂度。

其实还是有优化空间的,还是上述假设,x为质数时,2x真的需要我们标记吗?

不用!在搜索到质数2时,上面的2x已经标记过了,搜索到x时再标记2x反而增加了从不必要的操作。

代码实现

改良枚举:

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;}
};

n == 5000000时报超出时间限制

埃氏筛:

class Solution {public:int countPrimes(int n) {int cnt = 0;vector<int> isPrime(n, 1);for(int i = 2; i < n; ++i){if(isPrime[i]){cnt++;if((long long) i * i < n){for(int j = i*i; j < n; j += i){isPrime[j] = 0;}}}}return cnt;}
};

运行结果:

【基础数学--埃氏筛】204. 计数质数相关推荐

  1. 筛选质数,埃氏筛和欧拉筛(线性筛)

    求len之内的所有的素数 除了比较常用的开根号的求法,还有两种更好的方法,埃氏筛和线性筛.其中埃氏筛更好理解,而线性筛(欧拉筛)不好理解但是更快. 埃氏筛 #include <bits/stdc ...

  2. LeetCode Algorithm 204. 计数质数

    204. 计数质数 Ideas 质数的题目相对来说是个很经典的内容,虽然枚举也可以解决,但是复杂度很高,所以决定用埃氏筛来实现. 埃氏筛的基本思想是:从2开始,将每个质数的倍数都标记成合数. Code ...

  3. 三种素数筛总结——(朴素筛,埃氏筛,线性筛)

    但行好事,莫问前程. 题目背景 题目:(leetcode)204.计数质数 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 . 对于这类求解素数个数有关的题目,通常采用质数筛算法. 本文不计 ...

  4. 【算法分析与设计】埃氏筛素数算法

    文章目录 素数 埃氏筛 算法思想 时间复杂度 Java编程实现 算法优化 素数 素数也称质数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数. 最基本的质数:2, 3, 5, 7, ...

  5. 素数筛选法(埃氏筛 欧拉筛)

    质数筛选法 文章目录 质数筛选法 前言 一.埃氏筛 O(nloglogn)O(nloglogn)O(nloglogn) 二.欧拉筛O(n)O(n)O(n) 总结 前言 当需要大范围内的素数时,例如1e ...

  6. 力扣——204. 计数质数

    题目 python代码 1.直接法 import timeitdef countPrimes(n):'''按照质数的定义,用常规的方法来取质数 '''primesList = []for i in r ...

  7. LeetCode从读题到自闭:204. 计数质数

    题目:统计所有小于非负整数 n 的质数的数量 示例 1: 输入:n = 10 输出:4 解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 . 示例 2: 输入:n = 0 输出: ...

  8. 埃氏筛与欧拉筛(线性筛)

    目录 一.前言 二.埃氏筛与欧拉筛(线性筛) 1.问题描述 2.基本思路 (1)埃氏筛法 (2)欧拉筛法 三.题例 1.上链接 2.简单思路 3.代码 (1)埃氏筛python版 (2)欧拉筛pyth ...

  9. 素数筛法详解:埃氏筛和欧拉筛

    文章目录 摘要 埃式筛 欧拉筛 超级详细的基础算法和数据结构合集: https://blog.csdn.net/GD_ONE/article/details/104061907 摘要 本文主要介绍埃氏 ...

最新文章

  1. 不到顶会现场也能听论文讲解?这个视频集合网站值得收藏
  2. java json设置编码_我们如何用Java编码JSON对象?
  3. 【死磕 Spring】----- IOC 之解析 bean 标签:解析自定义标签
  4. C++校招常见面试题(2019年校招总结)
  5. 王校长一分钟能吃多少热狗?| 小游戏
  6. 利用微软AntiXss Library过滤输出字符,防止XSS攻击
  7. Pycharm: 设置默认字符编码为 utf-8模版
  8. microsoftonenote_OneNote2017官方下载
  9. AI率先引领手机“视”界革命——旷视联合IDC最新出炉AI+手机行业白皮书!
  10. 使用C语言绘制变换前与变换后的三角形图形——变换矩阵
  11. VGA高速PCB布局布线设计指南
  12. 分析 BAT 互联网巨头在大数据方向布局及大数据未来发展趋势
  13. 面向对象的封装,继承,多态。
  14. Metric评价指标-Embedding Similarity
  15. 如何提升自身能力?不再平庸
  16. 解决flex-direction: column 之后元素宽度自动变为100%
  17. 从网上找的 visual studio 的各个版本下载地址,vs2010/vs2012/vs2013带注册码
  18. PAT L1-016 查验身份证
  19. 动环监测,机房监测解决方案
  20. 【一】Excel VBA开发 初探

热门文章

  1. 机器视觉软件开发前景
  2. 图解游泳教程,包你一看就会!
  3. 数据挖掘导论 笔记5
  4. 一些奇技淫巧(持续更新~)
  5. tzoj1063: 养兔子
  6. dropdown-toggle
  7. WPF系列教程(十二):控件类——前景背景、字体Background、Foreground、FontFamily、FontSize
  8. Apache/Tomcat/JBOSS/Nginx区别
  9. luogu 1044
  10. 加密算法——报文通信过程中数据加密方法的总结