题目:
Description:
Count the number of prime numbers less than a non-negative number, n.
提示:
求素数个数的比较快速的方法是“埃拉托斯特尼筛法”,其原理很简单,具体的解释可以点击该链接。
代码:
一个简单的“埃拉托斯特尼筛法”实现:
class Solution { public: int countPrimes(int n) { vector<bool> prime(n, true); prime[0] = false; prime[1] = false; for (int i = 2; 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); } };
上述代码在LeetCode上的执行时间超过了100ms,比预想中的要慢一些,这里面其实有很多可以优化的地方:
- 将vector替换成单纯的bool数组;
- 算法中,有很大一部分时间花在了筛去2的整数倍数字上,由于这些数字每隔2就出现一次,有明显的规律,因此我们可以忽略他们。
优化后的算法如下:
class Solution { public: int countPrimes(int n) { if (n <= 2) return 0; double c = sqrt(n); bool *bv = new bool[n]; for(int i = 3; i <= c; i += 2) if (!bv[i]) for(int j = i*i, k = i << 1; j < n; j += k) bv[j] = 1; int num = 1; for(int i = 3; i < n; i += 2) if(!bv[i]) num++; delete[] bv; return num; } };