超时解法:
一个个判断,肯定会超
常规解法:建立Boolean数组判断下标对应的数字是否为质数,不是的话为true,是的话为false
采用的思想为the Sieve of Eratosthenes,由小到大将一个数(>1等于1没必要,相当于比自身)的倍数标记为非质数。最下面一个也是这种思想。
public int countPrimes(int n){
boolean[] notPrime= new boolean[n];
int count= 0;
int loop= (int)Math.sqrt(n);
for(int i=2; i<n; i++){
if(!notPrime[i]){
count++;
}
for(int j=2; i*j<n && i<=loop; j++){
notPrime[i*j]= true;
}
}
return count;
}
原理大概是:
1. 大于2的偶数肯定不可能是质数,同时1也不是质数,所以初始判断质数的个数最多为n/2;
2. 1 2 3 4 5 6 7 8在n=【3,8】时质数的个数都符合规律n/2,故从9开始只判断奇数是否为质数即可。
public int countPrimes(int n) {
if (n < 3)
return 0;
boolean[] f = new boolean[n];
//Arrays.fill(f, true); boolean[] are initialed as false by default
int count = n / 2;
for (int i = 3; i * i < n; i += 2) {
if (f[i])
continue;
for (int j = i * i; j < n; j += 2 * i) {//由于一开始并没有将偶数索引标记为true,直接将他们的数量减去了,故该处判断要跳过偶数
if (!f[j]) {
--count;
f[j] = true;
}
}
}
return count;
}