前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >204. 计数质数

204. 计数质数

作者头像
张伦聪zhangluncong
发布2022-10-26 18:05:26
5720
发布2022-10-26 18:05:26
举报

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

示例:

代码语言:javascript
复制
输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。

解1:小学数学没有学好,先来一下质数定义。质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。暴力拆解,时间复杂度达不到,数很大时,耗时长。看解2。

代码语言:javascript
复制
这道题的关键点就在于如何更有效的判断一个数为质数
那么这里举几个例子
比如16,那么有1*16,2*8,4*4,8*2,16*1这几个整数相乘的结果等于16。
再来看一个,
25,1*25,5*5,25*1
20,1*20,2*10,4*5,5*4,10*2,20*1
那么这里可以发现有如下规律:
众多 i*j=n 中,总有一个小于并最接近sqrt(n)开根号的整数k,
使得以后的所有i*j开始变成j*i,也就是说,从k以后,
下一个i*j就会开始和前面的相同,所以这里可以将原本需要
从1开始循环判断到n的量缩减到
小于等于sqrt(n)
代码语言:javascript
复制
public int countPrimes(int n) {
        int count = 0;
        for (int i = 2; i < n; i++) {
            if (isPrime(i)) {
                count++;
            }
        }
        return count;
    }

    private boolean isPrime(int num) {
        if (num <= 1) {
            return false;
        }
        for (int i = 2; i * i <= num; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

解2:埃拉托色尼筛选法(the Sieve of Eratosthenes)简称埃氏筛法,是古希腊数学家埃拉托色尼(Eratosthenes 274B.C.~194B.C.)提出的一种筛选法。 是针对自然数列中的自然数而实施的,用于求一定范围内的质数,它的容斥原理之完备性条件是p=H~。

代码语言:javascript
复制
埃氏筛法步骤
(1)先把1删除(现今数学界1既不是质数也不是合数)
(2)读取队列中当前最小的数2,然后把2的倍数删去
(3)读取队列中当前最小的数3,然后把3的倍数删去
(4)读取队列中当前最小的数5,然后把5的倍数删去
(5)读取队列中当前最小的数7,然后把7的倍数删去
(6)继续下一个质数,同上
(7)如上所述直到需求的范围内所有的数均删除或读取
注:此处的队列并非数据结构队列,如需保留运算结果,处于
存储空间的充分利用以及大量删除操作的实施,建议采用链表的数据结构。
代码语言:javascript
复制
public int countPrimes(int n) {
        if ((n ^ 0) == 0 || (n ^ 1) == 0) {
            return 0;
        }
        //对应的数0,1,2,..,(n-1)
        boolean[] prime = new boolean[n];
        Arrays.fill(prime, true);
        //0和1肯定不是质数
        prime[0] = false;
        prime[1] = false;
        //从2开始
        for (int i = 2; i < n; i++) {
            if (prime[i]) {
                // 将i的2倍、3倍、4倍...都标记为非素数
                for (int j = i * 2; j < n; j = j + i) {
                    prime[j] = false;
                }
            }
        }
        //统计
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (prime[i]) {
                count++;
            }
        }
        return count;
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档