要求:找小于n的质数个数
思路:
法一:暴力显然可以但是太慢了,埃氏筛:若x为质数则其倍数为合数.isprime数组首先全部置1,标记质数为1,然后从2开始一个个筛掉合数,为什么j要从i开始?因为前面的例如2i被2标记过了,只要标记i*(i+1),i*(i+2),时间O(nloglogn)
class Solution {
public:
int countPrimes(int n) {
int num=0;
vector<int> isprime(n,1);
for(int i=2;i<n;++i){
if(isprime[i])++num;
for(int j=i;(long long)j*i<n;++j)
isprime[j*i]=0;
}
return num;
}
};
法二:线性筛,45仍会被3和5重复标记,维护一个素数数组,每次标记i*primes[j],3*15和5*9如何去掉?i=9时,素数3能整除9,所以说这里可以停下来了,不用遍历9*5=3*3*5,时间O(n)
class Solution {
public:
int countPrimes(int n) {
vector<int> primes;
vector<int> isprime(n,1);
for(int i=2;i<n;++i){
if(isprime[i])primes.push_back(i);
for(int j=0;(long long)primes[j]*i<n&&j<primes.size();++j){
isprime[primes[j]*i]=0;
if(i%primes[j]==0)break;
}
}
return primes.size();
}
};