当前位置 博文首页 > Inmaturity_7的博客:算法练习帖--48--计数质数(Java)

    Inmaturity_7的博客:算法练习帖--48--计数质数(Java)

    作者:[db:作者] 时间:2021-08-01 08:42

    计数质数

    一、题目简介

    统计所有小于非负整数 n 的质数的数量
    (题目来源:力扣(LeetCode))

    示例 1:
    输入:n = 10
    输出:4
    解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
    
    示例 2:
    输入:n = 0
    输出:0
    
    示例 3:
    输入:n = 1
    输出:0
    
    提示:
    0 <= n <= 5 * 106
    

    二、解决方法

    1. 暴力法

    class Solution {
        public int countPrimes(int n) {
            int ans = 0;
            //遍历小于n且大于等于2的所有数字
            for (int i = 2; i < n; ++i) {
                ans += isPrime(i) ? 1 : 0;
            }
            return ans;
        }
    	//判断这个数字是否为质数
        public boolean isPrime(int x) {
            for (int i = 2; i * i <= x; ++i) {
                if (x % i == 0) {
                    return false;
                }
            }
            return true;
        }
    }
    

    2. 埃氏筛
    维基百科的动画:
    在这里插入图片描述

    class Solution {
        public int countPrimes(int n) {
        	//新建一个长度为n的数组(1标记是质数,0代表不是质数)
            int[] primes=new int[n];
            //初始化全部为质数
            Arrays.fill(primes,1);
            int count=0;
            for (int i = 2; i < n; i++) {
                if(primes[i]==1){
                	//如果当前是质数,计数count++
                    count++;
                    //再从i*i开始遍历到n为止(不包含n),如果是i的倍数肯定不是质数,把它对应的下标赋值为0
                    if((long)i*i<n){
                        for (int j=i*i;j<n;j+=i){
                            primes[j]=0;
                        }
                    }
                }
            }
            return count;
        }
    }
    

    3. 埃氏奇数筛
    如上图,我们可以看到偶数占一半,提前去除就可以省下一半的时间了(偶数必不可能为质数,除了2)

    class Solution {
       public int countPrimes(int n) {
            //新建一个长度为n的数组(1标记是质数,0代表不是质数)
            int[] primes=new int[n];
            //初始化全部为质数
            Arrays.fill(primes,1);
            //判断当前是否超过了2(超过了2就要统计2这个质数)
            int count=n>2?1:0;
            for (int i = 3; i < n; i+=2) {//每次递增改成只遍历奇数
                if(primes[i]==1){
                    count++;
                    if((long)i*i<n){
                        for (int j=i*i;j<n;j+=i){
                            primes[j]=0;
                        }
                    }
                }
            }
            return count;
        }
    }
    
    cs