leetcode 204. 计数质数
问题描述
统计所有小于非负整数 n 的质数的数量。
示例:
输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
代码
若n=20,首先0,1不是质数.2是第一个质数,然后把20以内所有2的倍数划去.2后面紧跟的数即为下一个质数3,然后把3所有的倍数划去.3后面紧跟的数即为下一个质数5,再把5所有的倍数划去.以此类推.
class Solution {
public:
int countPrimes(int n) {
if(n < 3)return 0;
vector<bool> isprime(n+1,true);
int i,j,count = 0;
for(i = 2; i < n; i++)
{
if(isprime[i])
{
++count;
for(j = 2;i*j < n;++j)
{
isprime[i*j] = false;
}
}
}
return count;
}
};
结果:
执行用时 :100 ms, 在所有 C++ 提交中击败了50.82%的用户
内存消耗 :7.8 MB, 在所有 C++ 提交中击败了100.00%的用户
下面进行优化:考虑\(12 = 2\times 6 = 3\times 4 = \sqrt{12}\times\sqrt{12} = 4 \times 3 = 6 \times 2\),可以看到如果在 \([2,\sqrt{n}]\) 这个区间之内没有发现可整除因子,就可以直接断定 \(n\) 是素数了,因为在区间 \([\sqrt{n},n]\)也一定不会发现可整除因子,因此最外层遍历只需要到\(\sqrt{n}\)即可。针对内层遍历,仍然可以写为:
for(j = 2*i;j < n;j += i)
但我们看到:2是素数,因此\(2\times2,2\times3,2\times4,2\times5,...\)不是素数,
3是素数,因此\(3\times2,3\times3,3\times4,3\times5,...\)不是素数,
5是素数,因此\(5\times2,5\times3,5\times4,5\times5,...\)不是素数,
但是在遍历3是素数的时候\(3\times2\)已经考虑了,在遍历5是素数的时候\(5\times2,5\times3\)已经考虑了,\(5\times4\)在遍历素数2的时候也被考虑了,因此内层遍历从\(\sqrt{n}\)开始就行了。
class Solution {
public:
int countPrimes(int n) {
if(n < 3)return 0;
vector<bool> isprime(n+1,true);
int i,j,count = 0;
for(i = 2; i*i <= n; i++)
{
if(isprime[i])
{
for(j = i*i;j < n;j += i)
{
isprime[j] = false;
}
}
}
for(i = 2; i < n; i++)
if(isprime[i])
++count;
return count;
}
};
结果:
执行用时 :76 ms, 在所有 C++ 提交中击败了68.99%的用户
内存消耗 :8 MB, 在所有 C++ 提交中击败了99.83%的用户