题目
Description:
Count the number of prime numbers less than a non-negative number, n.
解析
就是判断n以内,不包含n的素数有多少个。
先贴出我的代码
class Solution {
public:
int countPrimes(int n) {
vector<bool> isPrimer(n+1,true);
for (int i = 2; i*i < n; i++)
for (int j = i*i; j < n;j = j+ i)
isPrimer[j] = false;
<span style="white-space:pre"> </span>int ret = 0;
for (int i = 2;i<n;i++)
{
if (isPrimer[i])
ret++;
}
return ret;
}
};
其实思路就是按照提示的来的
把提示也贴出来
比如100,先建立101个bool值的vector,第0元素没用,其实100也可以,我就是想正好对齐。表示下标位是否是一个素数。
我们从2开始,把2的倍数都去掉,标识为非素数,同理遍历后面的数字,但是不用全部遍历,因为n如果有sqrt(n)以上的数字分解,那么也必然有sqrt(n)以下的数字,那么会在前面的数字就标识好,不用浪费空间。
说一下如何把2的倍数去掉这一详细的流程。我们是从2*2开始遍历,然后不断加2,这些数字全部都是2的倍数,可以标为非素数。
同理,如果是3,则从9开始。为什么需要从i*i开始呢?这是因为i到i*i之间的数字如果可以分解,那么必然有小于i的因式,那么必然在遍历到i之前就已经判断它是非素数了,不用重复判断。
这个方法是官方的提示,但是却耗时很多,有点想不明白为什么,难道比别人一个个遍历还耗时?
参考了一下别人的,应该是自己从vector中去寻找有几个true时太耗时了。改正后代码如下
class Solution {
public:
int countPrimes(int n) {
vector<bool> isPrimer(n+1,true);
int ret = 0;
for (int i = 2; i < n; i++)
{
if (isPrimer[i])
{
if (i<sqrt(n))
{
for (int j = i*i; j < n;j = j+ i)
isPrimer[j] = false;
}
ret++;
}
}
return ret;
}
};
就是从2遍历到n,找到标记为质数的数去对他的倍数变为非质数,并统计质数个数。