leetcode 204 Count Primes

来源:互联网 发布:淘宝货到付款怎么买 编辑:程序博客网 时间:2024/06/06 20:38

本题使用传统方法,时间复杂度过高,会超时。从discuss学习了两种新的方法。

第一种方法:

Sieve of Eratosthenes
youtube视频讲解

class Solution {        public int countPrimes(int n) {        //Java对布尔数组初始化为false        boolean[] nf = new boolean[n];        if(n < 3) return 0;        int ans = 0;        for(int i = 2; i < n; i++){            if(nf[i] == false) ans++;            //将i的所有倍数都标记为不是素数            for(int j = 2; i * j < n; j++)                nf[i * j] = true;        }                return ans;    }}

第一种改进的方法相对比较好懂,第二种如下

参考GrubenM在38楼给出的解释,添加注释

public class Solution {    /**     * 题目:Count the number of prime numbers less than a non-negative number, n     * @param n a non-negative integer     * @return the number of primes less than n     */    public int countPrimes(int n) {        /**         * 根据题意知,n为0,1,2时结果均为0         */        if (n < 3) return 0;        /**          * 结果c最大为n中包含的奇数的数量,因为偶数不可能是素数。         */        int c = n / 2;        /**         * 数组s中元素为true表示该元素不是素数,并且在下面计算中偶数不考虑在内         */        boolean[] s = new boolean[n];        /**         * i从3开始,并且每次只判断奇数,因此每次+2         */        for (int i = 3; i * i < n; i += 2) {            if (s[i]) {                // 该元素不是素数,跳过                continue;            }            /**              * 从i开始,把所有含有i为因子的数全部标记为不是素数。             *              * i * i 以及 i * i + a * i都是含有i因子的数。             * 并且在下面循环中同样跳过偶数             * i为奇数,i*i也是奇数,但是奇数+奇数为偶数,故只循环i*i + 偶数的数             * 即只循环i*i + (even) * i             */            for (int j = i * i; j < n; j += 2 * i) {                // 将s[j]设为不是素数,并且count减一                if (!s[j]) {                    c--;                    s[j] = true;                    }                }            }        return c;    }}
原创粉丝点击