Count Primes
Description:
Count the number of prime numbers less than a non-negative number, n
Credits:
Special thanks to @mithmatt for adding this problem and creating all test cases.
题意:找出所有小于n的素数个数
解题思路:埃拉托斯特尼筛法
给出要筛数值的范围n,找出以内的素数。先用2去筛,即把2留下,
把2的倍数剔除掉;再用下一个素数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个素数5筛,
把5留下,把5的倍数剔除掉;不断重复下去......。
详细列出算法如下:
- 列出2以后的所有序列:
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 标出序列中的第一个素数,也就是2,序列变成:
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 将剩下序列中,划摽2的倍数(用红色标出),序列变成:
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 如果现在这个序列中最大数小于最后一个标出的素数的平方,那么剩下的序列中所有的数都是素数,否则回到第二步。
public class Solution {
public int countPrimes(int n) {
if(n <= 2) return 0;
int cn = 0;
int m = n / 2;
boolean[] notPrime = new boolean[m]; //默认全是素数 将全部偶数去掉提前优化,2单独计数
int sqrtN = (int)Math.sqrt((double)n);
for(int i = 3; i <= sqrtN; i += 2){ //i每次自增2
if(notPrime[i / 2]) continue;
int j = i * i / 2;
while(j < m){
notPrime[j] = true;
j += i;
}
}
//0下标表示元素2 1下标即为元素3
for(int i = 0; i < m ; i++){
if(!notPrime[i]){
cn++;
}
}
return cn;
}
}