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;
}
};