在算法竞赛中经常会遇到求质数的问题,这种题目一般都是要求出一定范围内[0,n]所有的质数或者质数的个数。最直接的思路就是根据质数的定义来判定一个数是不是质数(即一个数不能被除1和它本身外的任何数整除),如果我们需要对所有的数都这样进行判断,那么当n非常非常大的时候,这种算法的时间开销就会非常大,大概为O(n^2)。这个时候就可以使用筛法来快速地求出素数,筛法求素数的基本思路就是:除了0、1之外,所有的合数都是可以表示为比它小的一个素数的倍数,如果我们已知一个素数,那么我们可以把问题规定的范围内的所有该素数的倍数全都筛除,如果该范围内的所有的合数都被筛出,剩下的自然就都是素数了,时间复杂度大概为O(n)。

leetcode上面的一道题目:计数质数,一道典型求质数的题目,现在给出筛法求素数的解法:

class Solution {
public:int countPrimes(int n) {if(n==0||n==1)return 0;int count=0;bool isprime[n];//用来标记是否是素数的数组memset(isprime,1,sizeof(isprime));//首先假设所有的数都是素数isprime[0]=isprime[1]=0;//0、1不是素数for(int i=2;i<n;i++){if(isprime[i]==1){//如果是素数count++;//计数加一for(int j=2*i;j<n;j+=i)//将该质数的倍数标记为合数isprime[j]=0;}}return count;}
};

因为我们的算法相当于是从2到n遍历一遍,我们将整个isprime数组都初始化为1,也就是假设有的数开始都是质数,每当访问isprime[i]的时候,如果它是合数,那么在访问它之前它一定已经被比它小的因子素数给筛掉了,所以在这个for(int i=2;i<n;i++)的循环中,每次访问isprime数组的时候都能确定i是不是素数了。

仔细思考一下上面的这种算法:线性筛法虽然大大缩短了求素数的时间,但是实际上还是做了许多重复运算,比如2*3=6,在素数2的时候筛选了一遍,在素数为3时又筛选了一遍。那么我们如何做出优化呢?如果只筛选小于等于素数i的素数与i的乘积,既不会造成重复筛选,又不会遗漏。时间复杂度几乎是线性的。

下面给出优划过后的筛法代码:

class Solution {
public:int countPrimes(int n) {if(n==0||n==1)return 0;int count=0;bool isprime[n];//用来标记是否是素数的数组vector<int> su;//用来保存已经确定的素数memset(isprime,1,sizeof(isprime));//首先假设所有的数都是质数isprime[0]=isprime[1]=0;//0、1不是素数for(int i=2;i<n;i++){if(isprime[i]==1){//如果是素数count++;//计数加一su.push_back(i);}for(int j=0;j<su.size()&&i*su[j]<n;j++)isprime[su[j]*i]=0;//小于i的所有的素数与i相乘得到的都是合数}return count;}
};

可以看出优化之后的算法需要额外的空间存放vector<int> su来保存已经确定的素数,所谓空间换时间,这样的优化在刚才的基础上又减少了不少的时间复杂度。

筛法快速求素数——leetcode计数质数相关推荐

  1. 快速求素数表——埃氏筛法与欧拉筛法

    快速求素数表--埃氏筛法与欧拉筛法 快速求素数表埃氏筛法与欧拉筛法 埃氏筛法 埃氏筛法原理 埃氏筛法时间复杂度 埃氏筛法代码求出1000000以内的素数并且输出n个素数 欧拉筛法 欧拉筛法原理 欧拉筛 ...

  2. 埃拉托斯特尼筛法 快速查找素数

    埃拉托斯特尼筛法 快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个 ...

  3. 线性筛法求素数c语言,[算法]素数筛法(埃氏筛法线性筛法)

    一.素数筛的定义 给定一个整数n,求出[1,n]之间的所有质数(素数),这样的问题为素数筛(素数的筛选问题). 二.埃氏筛法(Eratosthenes筛法) 埃氏筛法又叫做Eratosthenes筛法 ...

  4. 【LeetCode】计数质数 [M](素数筛选)

    204. 计数质数 - 力扣(LeetCode) 一.题目 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 . 示例 1: 输入:n = 10 输出:4 解释:小于 10 的质数一共有 4 ...

  5. 一般筛法求素数+快速线性筛法求素数

    一般筛法求素数+快速线性筛法求素数 标签: 正则表达式算法优化扩展c 2010-08-22 01:28 28738人阅读 评论(8) 收藏 举报  分类: 算法学习资料(5)  版权声明:本文为博主原 ...

  6. 一般筛法和快速线性筛法求素数 求素数的一点总结

    素数总是一个比较常涉及到的内容,掌握求素数的方法是一项基本功. 基本原则就是题目如果只需要判断少量数字是否为素数,直接枚举因子2 ..N^(0.5) ,看看能否整除N. 如果需要判断的次数较多,则先用 ...

  7. 求素数: 一般线性筛法 + 快速线性筛法

    From: http://blog.csdn.net/dinosoft/article/details/5829550 素数总是一个比较常涉及到的内容,掌握求素数的方法是一项基本功. 基本原则就是题目 ...

  8. c语言 快速筛质数,快速筛素数(埃式筛+线性筛+Miller_Rabin算法)

    在CF上做到一道核心是需要筛出1~n所有素数的题目,然后刚好又没学过,就学习了快速筛素数的办法,基础的n根号n的算法这里大家每个人都知道吧QAQ,就不讲了,好像还是C语言上机说过的题目. 首先给大家介 ...

  9. 《ACM算法详解》— 求素数(质数)算法

    (不想做题了.....整理一些资料吧) 求素数(质数)算法 如果一个正整数只有两个因子,1和p,则p为素数 1.根据概念判断 bool isPrime(int n) {if(n < 2) ret ...

最新文章

  1. 双圆弧插值算法(二)
  2. php中一个经典的!==的用法
  3. Mybatis XML文件的异常
  4. 什么是初效过滤器_初效过滤器主要用于过滤多少微米的杂质?
  5. mysql genlog 分析_Mysq性能分析 —— Genral log(普通日志)与 Slow log(慢速日式)...
  6. Apache Flink在 bilibili 的多元化探索与实践
  7. 为了30分钟配送,盒马工程师都有哪些“神操作”?
  8. PLSQL快捷键使用,让你高速开发
  9. 更喜欢使用Stream到byte[]
  10. ACM程序设计选修课——1036: Hungar的菜鸟赛季(YY)
  11. 购物商城Web开发第十天
  12. SQL Server Storage
  13. 利用selenium框架爬取京东省市区数据时,网页里面内嵌的一个窗口遇到的NoSuchElementException的 bug,原因是iframe
  14. DataMatrix 数据容量
  15. 如何用python编写程序打开csv格式文件
  16. HTML5编写船上航行,描写帆船航行的诗句
  17. 【向生活低头】win10电脑使用录音机的注意事项
  18. Dracula这个东西
  19. MySQL--count函数如果得到null的处理方法
  20. 微信内置浏览器无法下载app(Android/ios)软件 微信内下载链接打不开的解决方法

热门文章

  1. Mil学习之Mim的简单操作
  2. 虚拟机计算机无法启动,vmware15创建虚拟机,vmware虚拟机无法启动
  3. 给linux虚拟机配置网络连接,VMVare虚拟机网络配置步骤
  4. 造梦西游ol服务器维护,新服好礼不间断 《造梦西游ol》新享事成
  5. 修改 下载仓库为淘宝镜像 npm config set registry https://registry.npmjs.org/, 如果要发布自己的镜像需要修改回来 npm
  6. Java程序编译后的扩展名_一个Java源程序经过编译后,得到的文件扩展名一定是.class。...
  7. 不到 20 行 Python 代码,轻松玩转波士顿矩阵图!
  8. java 与BO集成
  9. 手把手教你写 Socket 长连接
  10. UVa1220 Party at Hali_Bula