描述:统计所有小于非负整数n的质数的数量。

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

解题思路:

1、暴力破解

验证一个数是否为质数有很多方法。最容易想到的就是暴力破解,采用暴力计算一步步碾压过去的方法。虽然不是最优的,但是对于我们解题是最有效的。

public boolean isPrime(int n){for(int i = 2 ; i*i <= n ; i++){if(n % i == 0){return false;}}return true;}/*** @param n* @return*/public int countPrimes(int n) {int count = 0;for(int i = 2; i < n; i++){if(isPrime(i)){count++;}}return count;}

通过遍历2-n之间的数,判断是否存在整除的元素存在,存在则不是,反之则是。毕竟是暴力破解嘛,效率上肯定不会很满意,使用 isPrime 函数来辅助就很不高效,而且算法也存在冗余。在输入值很大的情况下,直接超时警告。

如何判断一个数是不是质数,只需稍微改动 isPrime 代码:


boolean isPrime(int n) {for (int i = 2; i * i <= n; i++)...
}

换句话说,i不需要遍历到n,只需要到sqrt(n)即可。举个栗子,假设n=8


8=2*4
8=sqrt(8)*sqrt(8)
8=4*2

可以看到最前面和最后面是反过来的,而临界点就是sqrt(n)。换句话说就是如果在[2,sqrt(n)]区间上不存在可整除因子,即可以断定是质数了。

2、高效实现:

高效解决这个问题核心思想是常规思想反着来:

从2开始,2是质数,那么2的倍数都不可能是质数了。2*2 = 4,2*3 = 6, 2*4 = 8 ...

从3开始,3是质数,那么3的倍数也都不可能是质数了。3*2 = 6,3*3 = 9,3*4 = 12...

所以到现在是不是明白这个算法的逻辑呢?

int countPrimes(int n) {boolean[] isPrim = new boolean[n];// 将数组都初始化为 trueArrays.fill(isPrim, true);for (int i = 2; i < n; i++) if (isPrim[i]) // i 的倍数不可能是素数了for (int j = 2 * i; j < n; j += i) isPrim[j] = false;int count = 0;for (int i = 2; i < n; i++)if (isPrim[i]) count++;return count;
}

如果上面的代码能够理解,那么已经掌握了整体思路,但还有两个细微的地方可以优化。

刚才判断一个数是否是质数的isPrime函数,由于因子对称性,只需要遍历[2,sqrt(n)]就够了。同样外层循环也是一样:

for (int i = 2; i * i < n; i++) if (isPrim[i]) ...

除此之外,内层的循环也是可以优化的。之前做法:


for (int j = 2 * i; j < n; j += i) isPrim[j] = false;

这样把i的整数倍都标记为false,但是仍然存在计算冗余。可以稍微优化一下,让j从i的平方开始遍历:

for (int j = i * i; j < n; j += i) isPrim[j] = false;

这样,质数计算的算法就十分高效了,其实还有个名字,叫Sieve of Eratosthenes。。给出完整最终代码:

/*Sieve of Eratosthenes 算法*/public static int countPrimes3(int n) {boolean[] isPrim = new boolean[n];Arrays.fill(isPrim, true);for (int i=2;i*i<n;i++) {if (isPrim[i]) {for (int j = i*i;j<n;j+=i) {isPrim[j] = false;}}}int count = 0;for (int k=2;k<n;k++) {if (isPrim[k]) {count++;}}return count;}

以上就是质数算法相关的全部内容。感觉有么有很简单的样子


辛苦大佬看完,有兴趣的话可以关注下公众号,共同学习进步:

LeetCode-计数质数相关推荐

  1. 筛法快速求素数——leetcode计数质数

    在算法竞赛中经常会遇到求质数的问题,这种题目一般都是要求出一定范围内[0,n]所有的质数或者质数的个数.最直接的思路就是根据质数的定义来判定一个数是不是质数(即一个数不能被除1和它本身外的任何数整除) ...

  2. 20190911:(leetcode习题)计数质数

    计数质数 题目 大致思路 代码实现 题目 大致思路 实现埃拉托斯特尼筛法 遍历2-根号n,将2的倍数筛选出去,再把3的倍数筛出去,再把5的倍数筛出去-i的倍数筛出去 当i²>=n时跳出循环,剩下 ...

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

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

  4. LeetCode Algorithm 204. 计数质数

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

  5. 每天Leetcode 刷题 初级算法篇-数学问题-计数质数

    题目要求: 力扣题解: 代码 import java.util.Arrays;/*** @program: mydemo* @description: 力扣-数学-计数质数* @author: Mr. ...

  6. Day5:计数质数(埃拉托色尼筛选法)

    leetcode地址:https://leetcode-cn.com/problems/count-primes/ Day5:计数质数 一. 问题背景: 统计所有小于非负整数 n 的质数的数量. 二. ...

  7. 算法---计数质数(Java)

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

  8. 埃式筛/厄拉多塞筛法/Sieve_of_Eratosthenes/计数质数

    今天的每日一题是计数质数. 要求统计所有小于非负整数 n 的质数的数量. 为了解这题,学到了一个古老的魔法,快速寻找质数. 搜了下百度,keywords = "prime" &qu ...

  9. Leetcode 204. 计数质数 解题思路及C++实现

    解题思路: 利用一个数组记录 n 个数是否为质数. 质数的倍数都是非质数,就这样遍历下去就可以了. class Solution { public:int countPrimes(int n) {if ...

  10. leetcode 204. 计数质数

    题目 思路:厄拉多塞筛法 比如说求20以内质数的个数 首先 0, 1 不是质数 2 是第一个质数,然后把 20 以内所有 2 的倍数划去 2 后面紧跟的数即为下一个质数 3 , 然后把 3 所有的倍数 ...

最新文章

  1. 一个ThreadLocal和面试官大战30个回合
  2. oracle表空间 unifor,Oracle 表空间的监控
  3. finereport 登录界面的代码文件_Confluence 6 自定义登录界面
  4. 5月28日任务 Apache和PHP结合、Apache默认虚拟主机
  5. 搞事 | 5分钟部署一个机器人帮你告别 “信息焦虑”
  6. 电脑硬盘为什么叫计算机,电脑分区为何从C盘开始?
  7. 小爱同学App下架苹果App Store 网友:SiriOS警告?
  8. pdo mysql ascii_跟bWAPP学WEB安全(PHP代码)--SQL注入的一些技巧
  9. 关于linux低端内存
  10. grads插值_GrADS使用简介
  11. 为什么闹钟设置了却不响_为什么苹果手机闹钟设置了却不响
  12. Java时间处理第三方包:Joda-Time
  13. 抓取微博热搜榜数据并保存在Excel中
  14. Proxmox VE ZFS 开启Thin Provision(精简配置)
  15. 数据库 三级封锁协议
  16. Java程序入门教程 | Java
  17. 深度盘点:Python 使用和高性能技巧总结
  18. 苏州弗迈姆工业科技有限公司简介
  19. 【HR干货】劳动合同到底怎么签?掌握这几点很关键!
  20. outlook 发邮件时换行符号如何设置

热门文章

  1. 【java】关于Map的排序性的一次使用,有序的Map
  2. NVMe闪存存储系统设计挑战
  3. 虚拟机网络模式与网络配置
  4. Android消息传递之EventBus 3.0使用详解
  5. chrome插件:提取页面数据
  6. Exchange 服务器可支持性矩阵
  7. Nagios 安装方法
  8. NA-NP-IE系列实验44: 划分VLAN
  9. locktty锁终端的方法
  10. 开源漏洞扫描工具(OWASP-Dependency-Check)探索