[LeetCode] 204.计数质数(Easy)C语言题解

题目

  • 统计所有小于非负整数 n 的质数的数量。

示例

①示例1

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

说明

①相关话题

  • 哈希表
  • 数学

②相似题目

  • 263. 丑数 — 力扣网
  • 263. Ugly Number — leetcode
  • 264. 丑数 II — 力扣网
  • 264. Ugly Number II — leetcode
  • 279. 完全平方数 — 力扣网
  • 279. Perfect Squares — leetcode

③题目地址

  • 204. 计数质数 — 力扣网
  • 204. Count Primes — leetcode

解题方法

①数学知识

  • 质数(prime number)又称素数。即在大于 1 的自然数中,除了 1 和它本身外不再有其他因数。
  • 埃拉托斯特尼筛法:简称埃氏筛或爱氏筛,是由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数 n 以内的全部素数,必须把不大于根号 n 的所有素数的倍数剔除,剩下的就是素数。

②暴力解法

  • 两层 for 循环暴力判断。
  • 时间复杂度:O(N^2)。
  • 空间复杂度:O(1)。

③哈希表 + 埃拉托斯特尼筛法

  • 埃拉托斯特尼筛法证明图
  • 根据其数据范围动态创建数组,然后用数组模拟的哈希表求解。
  • 将所有素数(不大于根号 n)的倍数剔除后,计数质数即可。
  • 时间复杂度:O(N)。
  • 空间复杂度:O(N)。

代码详解

  • 暴力解法
int countPrimes(int n) {
    int count = 0;
    
    if (n > 2)
        count++;
    if (n > 3)
        count++;
    
    // 先排除偶数。
    for (int i = 5; i < n; i += 2) {
        int s = sqrt(i);
        
        // 根据质数性质,只需要判断其是否可以整除2-sqrt(i),就可知其是否是质数。
        for (int j = 2; j <= s; j++) {
            if (i % j == 0)
                break;
            if (j == s)
                count++;
        }
    }
    
    return count;
}
  • 哈希表 + 埃拉托斯特尼筛法
int countPrimes(int n) {
    int count = 0, s = sqrt(n);
    int* arr = malloc(sizeof(int)*n);
    
    if (n > 2) {
        // 初始化哈希表。
        for (int i = 2; i < n; i++) 
            arr[i] = 1;
        for (int i = 2; i <= s; i++) {
            if (arr[i]) {
                // 注意:是剔除其倍数,而不是平方数。
                for (int j = i*2; j < n; j += i)
                    arr[j] = 0;
            }
        }
        // 计数质数(剔除了所有非质数)。
        for (int i = 2; i < n; i++) {
            if (arr[i])
                count++;
        }
    }
    
    return count;
}

附录

  • 我的个人博客:messi1002.top
  • 如有错误或疑惑之处 请联系 [email protected]
  • 所有题目解答:fork me on github

你可能感兴趣的:(LeetCode-C,LeetCode-C)