题意:给定一个数n,求小于n的所有素数的个数
解题思路:如果是按照正常计算素数的方法解题一定会超时。
这是超时情况的代码:
class Solution {
public:
int countPrimes(int n) {
int i,j;
int num=0;
if(n>2)
num++;
for(i=3;i<n;i+=2)
{
for(j=2;j<=sqrt(i);j++)
{
if(i%j==0)
break;
}
if(j>sqrt(i))
{
num++;
}
}
return num;
}
};
正确做法:根据素数的特点,素数都为奇数(除了2),为了降低时间复杂度,对于小于n的数,我们只要考虑小于n的奇数。
其次,得到一个奇数后我们并不判断这个数是否为素数,而是去排除该奇数的倍数的可能,比如说;得到一个奇数3,直接可以排除3的倍数9,12,15......是素 数。这里为什么是从n*n开始排除而不是从2*n开始排除呢?因为n*(2到n)的数字之前已经被排除过了。比如说:一个奇数5,要从5*5开始排除,5*3已经被前面的3*5排除过了,这样可以不用去重复排除,从而提高效率。
可能讲的还不是很清楚,看源码更容易理解。
源码附上
class Solution {
public:
int countPrimes(int n) {
vector<bool> prime(n, true);
prime[0] = false, prime[1] = false;
for (int i = 0; i < sqrt(n); ++i) {
if (prime[i]) {
for (int j = i*i; j < n; j += i) {
prime[j] = false;
}
}
}
return count(prime.begin(), prime.end(), true);
}
};