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%的用户

参考

posted @ 2020-03-20 09:09  曲径通霄  阅读(161)  评论(0)    收藏  举报