[LeetCode]Count Primes

来源:互联网 发布:群晖nas网络存储 编辑:程序博客网 时间:2024/05/09 18:51

Question

Description:

Count the number of prime numbers less than a non-negative number, n.


本题难度Easy。

题意

找到n以内(不含n)的素数的个数。1不是素数。

埃拉托斯特尼筛法 Sieve of Eratosthenes

复杂度

时间 O(NloglogN) 空间 O(N)

思路

如果一个数是另一个数的倍数,那这个数肯定不是素数。利用这个性质,我们可以建立一个素数数组,从2开始将素数的倍数都标注为不是素数。第一轮将4、6、8等标记为非素数,然后遍历到3,发现3没有被标记为非素数,则将6、9、12等标记为非素数,(当遍历到4,它是合数就不用再计算4的倍数,因为4的倍数在2上已经标记过了)一直到N为止,再数一遍素数数组中有多少素数。

  • 创建数组个数为n个是为了方便进行映射:i->primes[i]
  • 最后统计时候并不统计0和1,所以从2开始

代码

public class Solution {    public int countPrimes(int n) {        //require        if(n<=1)return 0;        boolean[] primes=new boolean[n];        Arrays.fill(primes,true);        //invariant        for(int i=2;i<n;i++)            if(primes[i])                for(int j=2;j*i<n;j++)                    primes[j*i]=false;        int cnt=0;        for(int i=2;i<n;i++)//不统计0和1            if(primes[i])cnt++;        //ensure        return cnt;    }}

Follow up

其实也可以改为集合法,不过超时。

public class Solution {    public int countPrimes(int n) {        //require        if(n<=1)return 0;        Set<Integer> set=new HashSet<>();        for(int i=2;i<n;i++)set.add(i);        //invariant        for(int i=2;i<n;i++)            if(set.contains(i))                for(int j=2;j*i<n;j++)                    set.remove(i*j);        //ensure        return set.size();    }}

参考

[Leetcode] Count Primes 数素数

0 0