计数质数(简单)
2020年5月27日
题目来源:力扣
解题
质数写法的固化思维使人第一想法就写出下面的代码
class Solution {
public int countPrimes(int n) {
int count=0;
for(int i=1;i<n;i++){
if(ifPrimes(i))
count++;
}
return count;
}
public boolean ifPrimes(int n){
if(n==1) return false;
for(int i=2;i<=Math.sqrt(n);i++){
if(n%i==0)
return false;
}
return true;
}
}
厄拉多塞筛法
通过质数推算出接下来的非质数,一直算到n。
举个例子:
质数2,我们可以推算出2X2=4、2X3=6、2X4=8等,能发现质数的倍数都是非质数,标记下来
接下来到质数3,我们可以推算出3X2=6、3X3=9、3X4=12等,这里能发现一个可以优化的点,3X2=6这个点已经在2X3=6时标记它为非质数过了,现在是冗余操作,可以让质数3从3X3=9开始往后推算,那就是从质数i的iXi开始
接下来是到4了,之前我们在质数2的时候就标记了4是非质数,所以跳过它,不做它的倍数推算
通过这个例子,大概能了解厄拉多塞筛法在这道题的做法,是用空间来换时间的一种算法,通过结果也很明显的看出来这一点。
class Solution {
public int countPrimes(int n) {
int count=0;
//创建一个大小为n的布尔数组来存储所有数是否为非质数
boolean []bo=new boolean[n];
//循环根号n次就能找到所有的非质数
for(int i=2;i<=Math.sqrt(n);i++){
//如果是质数,就把所有质数的倍数设定为非质数
if(!bo[i])
for(int j=i*i;j<n;j+=i){
bo[j]=true;
}
}
//遍历计算质数个数
for(int i=2;i<n;i++){
if(!bo[i]) count++;
}
return count;
}
}