1.题目
统计所有小于非负整数 n 的质数的数量。
点击跳转原文
2.思路
写isPrime函数用于判断该数字是否为素数
bool isPrime(int n){
if(n==1) return false;
else if(n==2) return true;
else{
for(int i=2;i<=n/2;i++){
if(n%i==0){
return false;
break;
}
}
}
return true;
}
int countPrimes(int n){
int count=0;
for(int i=1;i<n;i++){
if(isPrime(i)){
cout<<i<<" " ;
count++;
}
}
return count;
}
此方法在输入499979的时候超出时间限制;
将传统的判断素数的函数改变一下:
大于等于5的质数一定和6的倍数相邻。例如5和7,11和13,17和19等等;
换句话说:不与6的倍数相邻的数一定不是素数,与6的倍数相邻的数不一定是素数。所以我们先排除掉不与6相邻的数,再判断与6的倍数相邻的数是否是素数
int countPrimes(int n) {
int sum = 0;
if(n==0 || n==1) return 0;
for(int i=2; i<n; i++){
if(isPrime(i)) sum++;
}
return sum;
}
bool isPrime(int num){
if(num ==2|| num==3 )
return true ;
//不在6的倍数两侧的一定不是质数
if(num %6!= 1&&num %6!= 5)
return false ;
int tmp =sqrt( num);
//在6的倍数两侧的也可能不是质数
for(int i= 5;i <=tmp; i+=6 )
if(num %i== 0||num %(i+ 2)==0 )
return false ;
//排除所有,剩余的是质数
return true ;
}
3.优秀案例
class Solution {
public:
int countPrimes(int n) {
bool notePrime[n+1] = {0};
int cnt = 0, limit = sqrt(n);
for (int i =2; i <= limit; ++i){
if (!notePrime[i]){
for (int j = i*i ; j < n; j+=i){
notePrime[j] = true;
}
}
}
for (int i = 2; i < n; ++i){
if (!notePrime[i])
++cnt;
}
return cnt;
}
};