计数质数——厄拉多塞筛法

1. 题目描述
统计所有小于非负整数 n 的质数的数量。
2. 思路
(1)暴力解法(超出时间限制)
从2开始遍历,对每个数字检测是否为质数,直到n。
检测方法:如果从2开始到它本身(不包括本身)的范围,有一个数能被它整除,则说明这个数不是质数。
(2)优化的暴力解法(超出时间限制)
1)所有的偶数都不是质数,除了0,2,所以可以先筛选掉。
2)对正整数 n ,如果用2到 √n 之间(注意要包含边界)的所有整数去除,均无法整除,则n为质数。
对条件(2)进行处理时,对于除数,可以跳过所有的偶数部分,即从3开始检测,每次+2。
(3)厄拉多塞筛法
在进行顺序遍历时,每取得一个数(排除0、1),遍历它之后所有小于n的数,将它所有的倍数(排除0、1、本身)都清除,那么,剩下的数则为质数。比如取得2,则排除小于n的所有倍数。
3. 代码

(1)暴力解法

	public int countPrimes1(int n) {
        if(n < 2)
            return 0;
        int res = 0;
        for(int i = 2; i < n; i++){
            boolean flag = true;
            for(int j = 2; j < i; j++){
                if(i % j == 0){
                    flag = false;
                    break;
                }
            }
            if(flag)
                res++;
        }
        return res;
    }

(2)优化的暴力解法

	public int countPrimes2(int n) {
        if(n <= 2)
            return 0;
        int res = 1;//2为质数
        for(int i = 3; i < n; i++){
            boolean flag = true;
            //如果可以整除2,则不是偶数,所以可以先筛选掉所有偶数
            if((i & 1) == 0){
                continue;
            }
            //对正整数 n ,如果用 2 到 √n 之间(注意要包含边界)的所有整数去除,均无法整除,则 n 为质数。
            for(int j = 3; j * j <= i; j = j+2){//由于前面已经筛掉所有负数,所以j可以+2跳过偶数部分
                if(i % j == 0) {
                    flag = false;
                    break;
                }
            }
            if(flag)
                res++;
        }
        return res;
    }

(3)厄拉多塞筛法

public int countPrimes3(int n) {
        if(n <= 2)
            return 0;
        boolean[] flag = new boolean[n];//不包括n
        //初始化设置所有的数为质数
        Arrays.fill(flag, true);
        int res = 0;
        for(int i = 2; i < n; i++){
            if(flag[i])
                res++;
            //i的所有倍数均不为质数
            for(int j = i + i; j < n; j = j+i){
                flag[j] = false;
            }
        }
        return res;
    }

参考链接:https://leetcode-cn.com/problems/count-primes/solution/ji-shu-zhi-shu-bao-li-fa-ji-you-hua-shai-fa-ji-you/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值