文章目录
- 一【题目类别】
- 二【题目难度】
- 三【题目编号】
- 四【题目描述】
- 五【题目示例】
- 六【题目提示】
- 七【解题思路】
- 八【时空频度】
- 九【代码实现】
- 十【提交结果】
一【题目类别】
- 数组
二【题目难度】
- 中等
三【题目编号】
- 204.计数质数
四【题目描述】
- 给定整数
n
,返回 所有小于非负整数n
的质数的数量 。
五【题目示例】
-
示例 1:
- 输入:n = 10
- 输出:4
- 解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
-
示例 2:
- 输入:n = 0
- 输出:0
-
示例 3:
- 输入:n = 1
- 输出:0
六【题目提示】
- 0 < = n < = 5 ∗ 1 0 6 0 <= n <= 5 * 10^6 0<=n<=5∗106
七【解题思路】
- 该题如果使用暴力方法,那么很简单:
- 遍历每个数字
- 判断每个数字都否是质数
- 不过暴力方法的时间复杂度很高,本题的测试用例无法通过
- 暴力方法超时的原因在于需要逐一判断每个数字,所以我们对其进行优化,即采用埃拉托斯特尼筛法进行计算:
- 最开始我们假设所有数字都是质数
- 然后从2开始遍历到 n \sqrt{n} n
- 如果当前遍历到的数字为质数,那么设置其所有倍数都是质数
- 最后返回质数的数量即可
- 具体细节可以参考下面的代码
八【时空频度】
- 时间复杂度: O ( n l o g l o g n ) O(n log log n) O(nloglogn),其中 n n n为传入参数的值
- 空间复杂度: O ( n ) O(n) O(n),其中 n n n为传入参数的值
九【代码实现】
- Java语言版
class Solution {public int countPrimes(int n) {// 初始化时假设所有数字都是质数boolean[] isPrime = new boolean[n];// 使用埃拉托斯特尼筛法进行计算for (int i = 2; i < Math.sqrt(n); i++) {// 如果当前数字为质数,那么其所有倍数都是质数(注意范围不要超过给定值)if (isPrime[i] == false) {for (int j = i * i; j < n; j += i) {isPrime[j] = true;}}}// 最后筛选剩下的就是所有质数,计算其数量即可int count = 0;for (int i = 2; i < n; i++) {if (isPrime[i] == false) {count++;}}return count;}
}
- Python语言版
class Solution:def countPrimes(self, n: int) -> int:# 初始化时假设所有数字都是质数is_prime = [True] * n# 使用埃拉托斯特尼筛法进行计算for i in range(2, int(n ** 0.5) + 1):# 如果当前数字为质数,那么其所有倍数都是质数(注意范围不要超过给定值)if is_prime[i]:for j in range(i * i, n, i):is_prime[j] = False# 最后筛选剩下的就是所有质数,计算其数量即可return sum(is_prime[2:])
- C语言版
int countPrimes(int n)
{// 初始化时假设所有数字都是质数int* isPrime = (int*)calloc(n, sizeof(int));// 使用埃拉托斯特尼筛法进行计算for (int i = 2; i < sqrt(n); i++){// 如果当前数字为质数,那么其所有倍数都是质数(注意范围不要超过给定值)if (isPrime[i] == 0){for (int j = i * i; j < n; j += i){isPrime[j] = 1;}}}// 最后筛选剩下的就是所有质数,计算其数量即可int count = 0;for (int i = 2; i < n; i++){if (isPrime[i] == 0){count++;}}free(isPrime);return count;
}
十【提交结果】
-
Java语言版
-
Python语言版
-
C语言版