2974 字
15 分钟
算法概述

复习#

核心问题:

  • 算法是什么?
  • 怎么描述算法?
  • 怎么分析算法?
  • 怎么设计算法(贪心初探)?
  • 怎么判断问题有多难(NP)?

Q&A#

算法的定义
算法的基本特性(5个)
算法与程序的区别?
伪代码怎么写?格式约定?
算法设计的过程,以及贪心算法初步理解
算法复杂度分析包含(2个)?影响时间复杂性的因素?(3个)
渐进符号的含义(4个)
说出具体含义-算法的性质:稳定性、最优性、随机性、在线/离线、近似比
计算复杂性理论(4个问题)
五大经典算法设计策略:贪心算法、动态规划、分治法、回溯法、分支限界法

一、什么是算法#

算法的定义#

算法(Algorithm) 是对特定问题求解步骤的一种描述,是若干条指令组成的有穷序列。

算法就是”解决问题的方法步骤”。

完整例子:求连续自然数和

问题: 求 a1,a2,…,ana_1, a_2, \dots, a_n 共 nn 个连续自然数的和。

  • 输入:a1a_1、nn
  • 输出:从 a1a_1 开始的 nn 个连续自然数的和 sumsum
  • 步骤:从 a1a_1 开始,累加 n−1n-1 次

算法的五大基本特性#

特性含义
输入算法可以有零个或多个输入,是算法运行的起点
输出算法必须至少有一个输出,体现算法价值
确定性每一步都有明确的指令,无歧义
有穷性(有限性)能在有限步内完成,避免无限循环
可行性每一步都能用已实现的基本运算执行有限次完成,现实可执行
注意

可行性 意味步骤必须是”现实可实现”的,不能出现无法实现的操作;确定性 + 有穷性 是算法能有效运行的关键。

算法 vs 程序#

对比算法程序
本质解决问题的步骤/思想步骤的代码实现
有穷性必须有限步终止可以无限运行
语言依赖不依赖编程语言必须用某语言实现
核心区别

程序可以不满足有限性。例如操作系统是持续运行的程序,需要不断响应用户操作,无法在有限步内终止;而算法必须终止。


二、算法的描述方式#

自然语言直观但可能不精确;伪代码更接近编程语言、逻辑清晰;也可以用 C++/Java/Python 等实际语言描述。

伪代码约定#

结构写法
赋值←
分支if...then...else...
循环while、for、repeat until
跳转goto
输出return
注释//
练习1:最大公约数 gcd(辗转相除法)
算法:gcd(m, n)
输入:非负整数 m, n(不全为 0)
输出:m 与 n 的最大公约数
1. while m > 0 do
2. r ← n mod m
3. n ← m
4. m ← r
5. return n
练习2:顺序查找 Search
算法:Search(L, x)
输入:数组 L[0..n],元素 x
输出:若存在返回位置,否则返回 -1
1. i ← 0
2. while (i < n) do
3. if (L[i] = x) then
4. return i
5. i++
6. return -1

三、算法设计——调度问题(贪心初步)#

问题: 有 nn 个任务,加工时间已知为 tit_i(i=1,2,…,ni=1,2,\dots,n),从 0 时刻起在一台机器上加工。每个任务的完成时间是从 0 时刻到该任务加工完成的时间。求总完成时间最短的调度方案。

贪心策略

加工时间短的任务优先(最短作业优先 SJF)。

  • 实例:t1=3,t2=8,t3=5,t4=10,t5=15t_1=3, t_2=8, t_3=5, t_4=10, t_5=15
  • 方案:(1, 3, 2, 4, 5)
  • 总完成时间 =5t1+4t3+3t2+2t4+t5=94= 5t_1+4t_3+3t_2+2t_4+t_5 = 94
*正确性证明——相邻交换论证

假设 I∗I^* 不是最佳调度,则存在调度 II 使 t(I∗)>t(I)t(I^*) > t(I),即 I∗I^* 中有作业未按处理时间升序排列。

那么在 I∗I^* 中存在相邻逆序任务 i,ji, j(ti>tjt_i > t_j)。交换后得到调度 II(序列 j,ij, i):

t(I∗)−t(I)=ti−tj<0t(I^*) - t(I) = t_i - t_j < 0

不符合 t(I∗)−t(I)>0t(I^*) - t(I) > 0,矛盾。故 I∗I^* 必为最佳调度。

算法设计的一般过程#

  1. 充分理解要解决的问题
  2. 问题建模(输入、条件、目标)
  3. 选择算法设计策略
  4. 算法描述
  5. 算法的正确性验证(若存在反例,找出来)
建模与数据结构的关系

问题建模是把现实问题转化为计算机可处理模型;数据结构是存储模型数据的载体。建模决定需要什么数据,数据结构服务于模型,反过来约束建模方案。


四、算法复杂性分析 ⭐(重点)#

为什么要做复杂性分析?#

算法复杂性主要指时间复杂性和空间复杂性,分析的是输入规模增大时资源开销的增长趋势,而非单纯算”跑多少秒、占多少内存”。

  • 机器无关,评价算法本身优劣
  • 预判大规模数据下程序会不会失效(最重要现实意义)
  • 指导算法设计与选择,做取舍
  • 区分”能跑通”和”高效”

算法的性质(评价指标)#

性质含义
正确性部分正确(终止则结果正确)/ 完全正确(必然终止且正确)
终止性算法必须终止
健壮性(鲁棒性)面对非法/异常/边界输入不崩溃,能识别并提示
可读性逻辑/伪码/代码易于人阅读理解
最优性问题最优 或 达到理论下界
可维护性/复用性是否易修改扩展、可复用
稳定性(排序特有)相等关键字相对位置不变则稳定。归并稳定;快排、堆排不稳定
近似比(近似算法)输出解与全局最优解的偏离程度
在线/离线离线:输入全部已知再算;在线:输入逐个到来即时决策(竞争比)
并行性是否易拆分为并行执行
随机性Monte-Carlo(时间确定、结果小概率错)/ Las-Vegas(结果必对、时间随机)
局部性时间/空间局部性,影响缓存命中率

时间复杂性的三种情况#

情况含义关注度
最坏情况算法性能上限最重要,有现实意义
最好情况最优条件下的性能较少关注,不能反映普遍性能
平均情况一般情况性能贴近实际,N→∞N \to \infty 用渐近式简化

影响时间复杂性的因素:问题规模 NN、输入实例 II、算法本身 AA。

渐近性态#

当 N→∞N \to \infty 时,若 T(N)−Φ(N)T(N)→0\dfrac{T(N) - \Phi(N)}{T(N)} \to 0,则 Φ(N)\Phi(N) 是 T(N)T(N) 的渐近性态。

渐近性态简化了复杂性分析:只要关注阶,忽略常数因子。

例子
  • T1(n)=30n4+20n3+40n2+46n+100≈n4T_1(n) = 30n^4 + 20n^3 + 40n^2 + 46n + 100 \approx n^4
  • T2(n)=1000n3+50n2+78n+10≈n3T_2(n) = 1000n^3 + 50n^2 + 78n + 10 \approx n^3

nn 很大时,算法 A 是 n4n^4,算法 B 是 n3n^3。

渐近记号 O / Ω / Θ / o#

记号含义对应情况直观
OO上界(渐进上界)最坏情况f(n)≤c g(n)f(n) \le c\,g(n)
Ω\Omega下界最好情况/至少f(n)≥c g(n)f(n) \ge c\,g(n)
Θ\Theta紧确界(上界=下界)平均情况上下界相同
oo严格上界更精确严格小于
核心理解

O(g(n))O(g(n)) 是一个函数集:其中每个函数 h(n)h(n) 都满足 h(n)≤c⋅g(n)h(n) \le c \cdot g(n)(cc 为常数,n≥1n \ge 1)。

上界越低、下界越高,评估越精确。

O(n) 复杂度的判断(重要)
  • log⁡n\log n、nlog⁡nn \log n、1000n21000n^2、10n2+100n10n^2+100n 都是 O(n2)O(n^2) 的
  • O(n)=O(n2)O(n) = O(n^2) ✓ (nn 是 n2n^2 的子集,同集关系)
  • O(n2)=O(n)O(n^2) = O(n) ✗ (n2n^2 不可能是 nn 的上界)

O 记号的性质#

  • O(f)+O(g)=O(max⁡(f,g))O(f) + O(g) = O(\max(f, g))
  • O(f)+O(g)=O(f+g)O(f) + O(g) = O(f + g)
  • O(f)⋅O(g)=O(fg)O(f) \cdot O(g) = O(fg)
  • 若 g(n)=O(f(n))g(n) = O(f(n)),则 O(f)+O(g)=O(f)O(f) + O(g) = O(f)
  • O(Cf(n))=O(f(n))O(Cf(n)) = O(f(n))(CC 为正常数)
  • f=O(f)f = O(f)

常见复杂度形态(从快到慢)#

O(1)<O(log⁡n)<O(n)<O(nlog⁡n)<O(n2)<O(2n)O(1) < O(\log n) < O(n) < O(n \log n) < O(n^2) < O(2^n)
注意

不同复杂度在 nn 增大时差距巨大。O(nlog⁡n)O(n \log n) 与 O(n2)O(n^2) 在数据量达到百万级时可能相差数万倍。


五、NP 完全性理论 ⭐#

计算复杂性理论#

研究计算问题本身有多难(需要多少资源、分属于哪个难度类),而非某个具体程序怎么写。标准计算模型是图灵机。

问题分类#

类全称含义
PPolynomial多项式时间可解(容易,如排序)
NPNondeterministic Polynomial多项式时间可验证(解验证容易、求解困难)
NP-hardNP 难至少和 NP 里最难的问题一样难;不一定属于 NP。能解决一个 NP-hard 问题就能解决全部 NP 问题
NPCNP 完全NP 中最难的一类,既是 NP 又是 NP-hard
关键关系
  • P⊆NPP \subseteq NP(P 中的判定问题也在 NP 中)
  • P = NP 猜想:P 类是否等于 NP 类,是计算机科学重大问题,至今未解决
  • 若某 NP-hard 问题 QQ 能在多项式时间求解,则 P = NP
  • 若 P≠NPP \ne NP,则 NP 难问题都不能在多项式时间求解

典型 NP 问题#

SAT(布尔可满足性,Satisfiability)——计算机科学最重要的问题:

给定一个合取范式(CNF)F=F(x1,x2,…,xn)F = F(x_1, x_2, \dots, x_n),是否存在一组布尔赋值 x1…xn∈{0,1}x_1\dots x_n \in \{0,1\} 使得 F=TrueF = True?

IS(独立集问题,Independent Set)——第二重要的问题:

给定图 GG 和整数 kk,能否在 GG 中找 kk 个点,使其中任意两点不相邻?

判定问题 vs 优化问题

讨论中一般关注判定问题(decision problems):证明解的存在性不难。给定了 kk 个点的集合 II(或一组赋值后),很容易判定 II 是不是独立集(或 CNF 是否可满足)。

判定问题与其对应的优化问题通常具有相似的复杂度,因此重点研究判定问题。

NP 完全问题#

  • Cook 定理:布尔表达式的可满足性问题(CNF-SAT、3-SAT)是第一个 NP 完全问题
  • 多项式时间变换:NP 完全问题可在多项式时间内互相转换,因此可用已知 NPC 问题证明其他问题的复杂性

六、五大经典算法设计策略(总览)#

策略核心思想适用典型问题
贪心算法每一步取当前最优具有贪心选择性质活动选择、调度问题
动态规划求子问题并保存结果,避免重复计算重叠子问题 + 最优子结构背包问题
分治法分解子问题、分别求解、合并结果可分解可合并归并排序
回溯法(DFS)深度优先搜索 + 剪枝,不满足就回溯组合搜索八皇后
分支限界法(BFS)广度优先/最优优先 + 限界剪枝组合优化旅行售货员
注意

贪心算法不一定能得到全局最优解;动态规划和分治的关键都是拆解子问题并合理合并。


七、算法应用案例:传统算法 vs 机器学习#

特征传统算法机器学习算法
规则来源人为定义明确规则从数据自动学习
确定性给定输入输出确定可能概率性输出
适应性固定,除非修改通过新数据持续优化
性能评估时间/空间复杂度准确率、召回率、F1 分数
适用规则明确可建模规则复杂难显式描述
台风路径预测:物理驱动 vs 数据驱动
  • 传统数值预报(NWP): 物理驱动,可解释性强、外推稳定、输出全套气象要素;但计算开销巨大、依赖超算
  • 机器学习预测: 数据驱动、推理快、训练算力大;但黑盒、极端天气易失效、可能出现非物理结果
  • 当前定位: 物理 NWP 是核心主力,机器学习做辅助校正和快速集合预报

其他应用:图像识别(CNN)、推荐系统(协同过滤 + 冷启动挑战)、NLP(语言模型 + 语义歧义挑战)。

算法概述
https://entropy.lighterever.com/posts/算法概述/
作者
Lighterever
发布于
2026-09-09
许可协议
CC BY-NC-SA 4.0