玩命加载中 . . .

204-计数质数


LeetCode 204. 计数质数

给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。

示例 1:

输入:n = 10
输出:4
解释:小于 10 的质数一共有 4, 它们是 2, 3, 5, 7

method 1

直接遍历计算每个数是否是质数

bool isPrime(int x) {
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0) return false;
    }
    return true;
}
int countPrimes(int n) {
    int res = 0;
    for (int i = 2; i < n; i++) {
        if (isPrime(i)) res++;
    }
    return res;
}

method 2: 埃氏筛

如果 $x$ 是质数,那么大于 $x$ 的 $x$ 的倍数 $2x,3x,\ldots$ 一定不是质数

isPrime[i] 表示数 i 是不是质数,如果是质数则为 1,否则为 0。从小到大遍历每个数,如果这个数为质数,则将其所有的倍数都标记为合数(除了该质数本身),即 0,这样在运行结束的时候我们即能知道质数的个数

还可以继续优化,对于一个质数 $x$,如果按上文说的我们从 $2x$ 开始标记其实是冗余的,应该直接从 $x^2$ 开始标记,因为 $2x,3x,\ldots$ 这些数一定在 $x$ 之前就被其他数的倍数标记过了,例如 2 的所有倍数,3 的所有倍数等

int countPrimes(int n) {
    vector<int> isPrime(n, 1);
    int res = 0;
    for (int i = 2; i < n; i++) {
        if (isPrime[i]) res++;
        if ((long)i * i < n) {  // 会溢出
            for (int j = i * i; j < n; j += i) {
                isPrime[j] = 0;
            }
        }
    }
    return res;
}

文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录