leetcode #204 计数质数

61 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

计数质数

题目

204. 计数质数

难度中等

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

 

示例 1:

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

示例 2:

输入: n = 0
输出: 0

示例 3:

输入: n = 1
输出:0

暴力解法

function countPrimes(n: number): number {
  if (n < 2) return 0;
  let num = 0;
  for (let i = 2; i < n; i++) {
    if (primes(i)) {
      num++;
    }
  }
  return num;
}
const primes = (n: number): boolean => {
  for (let i = 2; i < n; i++) {
    if (n % i === 0) {
      return false;
    }
  }
  return true;
};

这也是我第一时间想到的解法,但我们都知道,这肯定是很费时间的,所以我们会优化算法,而且如果提交的话,会显示超时

筛选法

思想就是,我们从小到大开始遍历(从2开始),那么前面 2 3 5都是质数,而它们的2x | 3x| 4x ...都一定是非质数,就比如4: 它是2的2x,因此是非质数,而后面稍大的数,大部分都是前面2 3 5 等等小的数的倍数,而那些大的非质数,一定不是前面的质数的倍数,因此我们可以通过这个原理来筛选。

由上,我们通过一个数组来标记是否为质数,将质数的倍数设为非质数即可。

function countPrimes(n: number): number {
  // 求质数的数量
  // 原理就是从小到大遍历,质数的倍数一定是非质数,而对于后面较大的数,
  //如果前面没有质数的倍数是它的话,那么它也是质数
  if (n <= 2) return 0;
  let s: boolean[] = new Array<boolean>(n).fill(true);
  // true表示是质数
  let num = 0;

  for (let i = 2; i < n; i++) {
    if (s[i]) {
      num++;
      // 如果s[i]还未改变 那就说明它是质数
      for (let j = i; j < n; j += i) {
        // 否则让这非质数的倍数改变
        s[j] = false;
      }
    }
  }
  return num;
}
console.log(countPrimes(10));

总结

本次文章的难点在于筛选法的思考

结语

本次的文章到这里就结束啦!♥♥♥读者大大们认为写的不错的话点个赞再走哦 ♥♥♥

每天一个知识点,每天都在进步!♥♥