埃拉托斯特尼筛法
埃拉托斯特尼筛法
基本概念
- 核心定义:一种用于找出小于等于给定整数N的所有质数的古老算法。
- 核心思想:“排除法”。与其逐个判断每个数是不是质数,不如反过来:从 2 开始,把每一个质数的倍数全部标记为“合数(非质数)”。剩下的未被标记的数就是质数。
- 数据结构:通常使用一个布尔数组(Boolean Array)来维护状态。数组索引代表数字本身,值代表该数字是否为质数(
True/False)。
费曼理解 (Feynman Technique)
用最简单的语言解释给“小白”听:
想象操场上有编号 2 到 100 的 100 个学生,他们都默认站着(代表是质数)。
- 第一步:老师喊 2(最小的质数)。2 说:“凡是能被 2 整除的同学(4, 6, 8…),请坐下(排除)。”
- 第二步:老师喊下一个还站着的同学 3。3 说:“凡是能被 3 整除的同学(6, 9, 12…),请坐下。”
- 重复:老师继续找下一个还站着的同学(5, 7…),直到检查完 100100 (即 10)为止。
最后:操场上还站着的同学,他们的编号就是质数。
3. 内部实现:核心代码逻辑
1 | class Solution: |
代码逻辑拆解:
- 预处理:创建数组,排除 0 和 1。
- 外层循环:遍历 。为什么是 n ?因为如果n有一个大于 n 的因数,必然有一个小于n的对应因数,所以只需筛到n。
- 内层循环:关键优化点。对于质数i,我们从i×i开始标记,步长为i。这是因为 i×2,i×3…i×2,i×3… 在之前已经被 2, 3 筛过了,从 开始是效率最高的。
复杂度分析
| 指标 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(NlogN) | 这是一个非常接近线性的时间复杂度。虽然有两层循环,但由于内层循环只在 i 是质数时才执行,且步长递增,其数学期望极低。 |
| 空间复杂度 | O(N) | 需要一个长度为 N 的布尔数组来存储每个数的状态。 |
应用场景
埃拉托斯特尼筛法是预处理思想的典范,适用于以下场景:
-
批量查询:
- 当你需要多次查询某个数是否为质数时(例如查询 10000 次),先用筛法生成一张“质数表”,之后每次查询的时间复杂度仅为 O(1)。
-
统计区间质数:
-
数学计算:
- 在数论计算、密码学预处理、生成素数表等场景中不可或缺。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!










