leetcode-204.计数质数

141 阅读1分钟
/**
 * ref:https://leetcode-cn.com/problems/count-primes/
 * 统计所有小于非负整数 n 的质数的数量。
 * 示例 1:
 * 输入:n = 10
 * 输出:4
 * 解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
 **/
 
public class CountPrimes {

    public static void main(String[] args){
        System.out.println(countPrimes(100));
        System.out.println(eratosthenes(100));
    }

    /**
     * 统计0~n的质数个数
     * @param n
     * @return
     */
    public static int countPrimes(int n){
        int count = 0;
        for(int i=2;i<n;i++){
            count+= isPrimes(i)?1:0;
        }
        return count;
    }

    /**
     * 暴力破解法,从2开始遍历,判断是否能被2到自身之间的整除
     * 一个数可以整除1和自身的情况下,叫做质数
     * @param x
     * @return
     */
    public static boolean isPrimes(int x){
        // 一个整数i如果被x整除,则x/i肯定能被x整除,因此需要判断i到根号x之间值即可。
        for(int i=2;i*i<=x;i++){
            if(x%i==0){
                return false;
            }
        }
        return true;
    }

    /**
     * 埃氏筛法
     * 素数判断,可以排除掉合数。既两个素数的积肯定是合数也就是说,不是素数,直接跳转这个数的判断即可
     * @param n
     * @return
     */
    public static int eratosthenes(int n){
        // 给每个数的都创建一个对应的标记位,最后统计标记位是素数的个数
        boolean[] isPrime = new boolean[n];
        int count =0;
        // 从2开始迭代,由于1不是素数,不用统计
        for(int i=2;i<n;i++){
            // 不是合数
            if(!isPrime[i]){
                // 素数数量统计+1
                count++;
                // 标识相应的合数,
                // 迭代i=2的时候,初始化的值就是2*2=4,然后4+2=6,6+2=8等都就是合数,直至2的计算全部迭代完毕。
                // 然后进行下一轮迭代,i=3,初始化的值就是3*3=9,然后9+3=12,12+3=15等继续罗列
                for(int j=i*i;j<n;j+=i){
                    isPrime[j] = true;
                }
            }
        }
        return count;
    }

}