差别
这里会显示出您选择的修订版和当前版本之间的差别。
| 两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
| 数据结构:绪论 [2025/12/11 15:32] – [5. 动态规划 (Dynamic Programming)] 张叶安 | 数据结构:绪论 [2025/12/11 16:24] (当前版本) – [1. 穷举法 (Brute Force)] 张叶安 | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | ====== 绪论:数据结构与算法详解 ====== | + | ====== 绪论:数据结构与算法详解 |
| - | 程序设计的核心公式(N.沃思): | + | **"程序设计 = 数据结构 + 算法"** —— 尼克劳斯·沃思 (Niklaus Wirth, 图灵奖得主) |
| - | > **程序 | + | |
| - | | + | 如果把编程比作**烹饪**: |
| - | * | + | |
| + | * | ||
| + | |||
| + | 本教程旨在通过可视化的方式,深入剖析计算机科学的这两大基石。 | ||
| ===== 第一部分:数据结构 (Data Structure) ===== | ===== 第一部分:数据结构 (Data Structure) ===== | ||
| + | |||
| + | 数据结构不仅仅是存储数据,更是为了**高效地**检索和操作数据。 | ||
| ==== 1. 核心概念辨析 ==== | ==== 1. 核心概念辨析 ==== | ||
| - | 我们通过一个**“学生信息管理系统”**的例子来理解以下概念: | + | 在深入具体结构前,我们需要厘清以下术语的层级关系: |
| - | * **数据 (Data)**:计算机处理的符号总称。 | + | ^ 术语 ^ 定义 ^ 举例 (学生管理系统) ^ |
| - | | + | | **数据 (Data)** |
| - | * | + | | **数据元素 (Data Element)** |
| - | | + | | **数据项 (Data Item)** |
| - | | + | | **数据对象 (Data Object)** |
| - | | + | |
| - | * | + | |
| - | ==== 2. 逻辑结构:数据之间的“关系” ==== | + | ==== 2. 逻辑结构:数据之间的“思想关系” ==== |
| - | 逻辑结构描述的是数据在**思想上**的关联,与它们在电脑里存哪里无关。 | + | 逻辑结构是指数据元素之间的相互关系,它与数据在计算机中的存储位置无关。我们通常将其分为四类。 |
| - | + | ||
| - | ^ 类型 ^ 关系特点 ^ 生活中的例子 ^ 图示说明 ^ | + | |
| - | | **集合结构** | **松散**。除了“同在一个圈子”外,没别的关系。 | 操场上散开做操的同学。 | ( A B C ) | | + | |
| - | | **线性结构** | **一对一**。像一条线,有头有尾,前后相连。 | 排队打饭的队伍;挂在墙上的一串钥匙。 | A -> B -> C | | + | |
| - | | **树状结构** | **一对多**。层次分明,像倒过来的树。 | 电脑里的文件夹(C盘 -> 用户 -> 文档);家族族谱。 | A -> (B, C) | | + | |
| - | | **图形结构** | **多对多**。错综复杂,四通八达。 | 城市交通网;微信的好友关系网。 | A <-> B <-> C | | + | |
| - | + | ||
| - | ==== 3. 存储结构:数据在“内存”中的样子 ==== | + | |
| - | + | ||
| - | 这是逻辑结构在计算机中的**物理实现**。这是本章的重点,我们可以通过 HTML 可视化来理解。 | + | |
| < | < | ||
| - | <div style=" | + | <!DOCTYPE html> |
| - | < | + | <html lang="zh-CN"> |
| - | + | < | |
| - | | + | < |
| - | | + | /* 容器基础样式 */ |
| - | | + | .ds-container { |
| - | | + | font-family: |
| - | | + | |
| - | < | + | padding: 25px; |
| - | < | + | border-radius: |
| - | < | + | |
| - | < | + | max-width: 900px; |
| + | margin: 0 auto 20px auto; | ||
| + | | ||
| + | | ||
| + | display: grid; | ||
| + | grid-template-columns: repeat(auto-fit, minmax(220px, | ||
| + | gap: 25px; | ||
| + | | ||
| + | .ds-card { | ||
| + | background: white; | ||
| + | padding: 20px; | ||
| + | | ||
| + | box-shadow: 0 4px 6px rgba(0,0,0,0.05); | ||
| + | | ||
| + | transition: all 0.3s ease; | ||
| + | border-bottom: 3px solid transparent; | ||
| + | display: flex; | ||
| + | | ||
| + | align-items: | ||
| + | } | ||
| + | .ds-card: | ||
| + | transform: translateY(-7px); | ||
| + | box-shadow: 0 10px 20px rgba(0, | ||
| + | | ||
| + | } | ||
| + | .ds-icon-box { | ||
| + | height: 110px; | ||
| + | | ||
| + | display: flex; | ||
| + | align-items: center; | ||
| + | justify-content: center; | ||
| + | margin-bottom: | ||
| + | | ||
| + | border-radius: 8px; | ||
| + | } | ||
| + | .ds-svg { | ||
| + | | ||
| + | | ||
| + | overflow: visible; | ||
| + | } | ||
| + | .ds-shape { fill: #3498db; } | ||
| + | .ds-shape-2 { fill: #e74c3c; } | ||
| + | .ds-shape-3 { fill: #f1c40f; } | ||
| + | .ds-shape-4 { fill: #2ecc71; } | ||
| + | | ||
| + | .ds-dashed { stroke: #bdc3c7; stroke-width: 2; stroke-dasharray: 5,3; fill: none; } | ||
| + | | ||
| + | .anim-float-2 { animation: float 4s infinite ease-in-out 0.5s; } | ||
| + | .anim-float-3 { animation: float 3.5s infinite ease-in-out 1.2s; } | ||
| + | .anim-float-4 { animation: float 4.5s infinite ease-in-out 2s; } | ||
| + | @keyframes float { | ||
| + | 0%, 100% { transform: translateY(0); | ||
| + | 50% { transform: translateY(-4px); | ||
| + | } | ||
| + | h4 { margin: 0 0 8px 0; color: #2c3e50; font-size: 1.1em; font-weight: 700; } | ||
| + | p.desc { font-size: 0.9em; color: #7f8c8d; margin: 0; line-height: | ||
| + | p.example { font-size: 0.8em; color: #95a5a6; margin-top: 5px; font-style: italic; } | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <!-- 1. 集合结构 --> | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <svg class=" | ||
| + | <ellipse cx=" | ||
| + | <circle cx=" | ||
| + | <circle cx=" | ||
| + | <circle cx=" | ||
| + | <circle cx=" | ||
| + | <circle cx=" | ||
| + | <circle cx=" | ||
| + | </ | ||
| + | | ||
| + | < | ||
| + | <p class=" | ||
| + | <p class=" | ||
| </ | </ | ||
| - | < | + | |
| - | <span style="margin-left:15px;">addr:0</span> | + | |
| - | <span style="margin-left:20px;">addr:1</span> | + | <div class="ds-icon-box"> |
| - | <span style="margin-left:20px;">addr:2</span> | + | <svg class=" |
| - | <span style="margin-left:20px;">addr:3</span> | + | |
| + | <circle cx="20" cy=" | ||
| + | | ||
| + | <circle cx=" | ||
| + | | ||
| + | <circle cx="120" cy=" | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | <p class=" | ||
| + | <p class=" | ||
| </ | </ | ||
| - | </ | + | |
| - | + | < | |
| - | | + | <div class=" |
| - | < | + | <svg class=" |
| - | <strong>2. 链式存储 (Linked Storage) | + | |
| - | <p style="font-size:0.9em; color:#666;">特点:物理位置随意,靠“小纸条(指针)”指引下一站。</p> | + | <line x1="70" y1=" |
| - | <div style="display: flex; align-items: center; flex-wrap: wrap;"> | + | |
| - | <!-- Node 1 --> | + | <line x1=" |
| - | <div style="border:1px solid #333; display: | + | <line x1=" |
| - | <div style="padding: | + | <line x1=" |
| - | <div style="padding: | + | <circle cx=" |
| + | <circle cx=" | ||
| + | <circle cx="100" cy=" | ||
| + | <circle cx="20" | ||
| + | | ||
| + | <circle cx="85" cy=" | ||
| + | | ||
| + | </svg> | ||
| </ | </ | ||
| - | <div style="margin-right: | + | <h4> |
| - | + | <p class="desc">一对多的层级关系,严谨的分支体系。</p> | |
| - | < | + | |
| - | < | + | </ |
| - | <div style="padding: | + | |
| - | <div style="padding: | + | <div class=" |
| - | </div> | + | < |
| - | <div style="margin-right:5px; font-weight: | + | <svg class="ds-svg" |
| - | + | | |
| - | <!-- Node 3 --> | + | <line x1="70" y1=" |
| - | <div style="border:1px solid #333; display: | + | |
| - | <div style="padding: | + | <line x1=" |
| - | <div style="padding: | + | <line x1="40" y1=" |
| + | <line x1=" | ||
| + | | ||
| + | < | ||
| + | <circle cx=" | ||
| + | <circle cx="20" | ||
| + | <circle cx="120" | ||
| + | | ||
| + | <circle cx="100" cy=" | ||
| + | | ||
| </ | </ | ||
| + | < | ||
| + | <p class=" | ||
| + | <p class=" | ||
| </ | </ | ||
| </ | </ | ||
| </ | </ | ||
| + | </ | ||
| </ | </ | ||
| - | === 3.1 详细对比 | + | === 2.1 集合 (Set) === |
| + | * | ||
| + | * | ||
| - | | 特性 | 顺序存储 | + | === 2.2 线性结构 |
| - | | **物理位置** | 必须相邻。 | 可以不相邻,散落在内存各处。 | | + | * |
| - | | **关系表示** | 靠位置体现($A$ 的后面就是 $B$)。 | 靠指针体现($A$ 手里拿着 $B$ 的地址)。 | | + | |
| - | | **优点** | 查找快(直接算地址),存储密度大。 | 插入、删除快(不用移动元素,改指针即可)。 | | + | * |
| - | | **缺点** | 插入删除需要移动大量元素;需要预分配空间。 | 查找慢(必须从头找);指针占用额外空间。 | | + | * |
| + | * **栈 (Stack)**:后进先出 (LIFO),如弹夹。 | ||
| + | * | ||
| - | ===== 第二部分:算法 | + | === 2.3 树状结构 |
| + | * | ||
| + | * | ||
| - | 算法不仅要算出结果,还要算得“快”且“省”。 | + | === 2.4 图形结构 (Graph) === |
| + | * | ||
| + | * | ||
| - | ==== 1. 算法的五大特性 | + | ==== 3. 存储结构:数据在“内存”中的物理形态 |
| - | 记忆口诀:**有输(出)入,可行确(定)穷**。 | + | |
| - | - **有穷性**:算法不能陷入死循环,必须能跑完。 | + | |
| - | - **确定性**:代码不能模棱两可,同样的输入必须得到同样的输出。 | + | |
| - | - **可行性**:每一步都能通过有限次基本运算完成。 | + | |
| - | - **输入**:0个或多个(例如 `void print_hello()` 就没有输入)。 | + | |
| - | - **输出**:1个或多个(没有输出的算法是无意义的)。 | + | |
| - | ==== 2. 算法效率度量 ==== | + | 逻辑结构是“想出来的”,存储结构是“写在内存条上的”。 |
| - | 我们用 | + | === 3.1 顺序存储 (Sequential Storage) === |
| + | | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | | ||
| + | * | ||
| + | * | ||
| + | * | ||
| - | === 2.1 时间复杂度 | + | === 3.2 链式存储 |
| - | 随着数据量 $n$ 的增大,耗时增长的趋势。 | + | |
| + | * | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * | ||
| - | * **$O(1)$ 常数阶**:无论数据多少,耗时不变。 | + | === 3.3 索引存储与散列存储 === |
| - | * | + | |
| - | * **$O(n)$ 线性阶**:数据翻倍,耗时翻倍。 | + | * **散列存储 |
| - | * *例子*:遍历一个列表,找某个数。 | + | * 不通过比较,而是通过公式(哈希函数)直接计算出存储地址。 |
| - | * **$O(n^2)$ 平方阶**:数据翻倍,耗时变成 4 倍。 | + | * **冲突 |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | **效率排序**: | + | ===== 第二部分:算法 (Algorithm) ===== |
| - | $O(1) < O(\log n) < O(n) < O(n \log n) < O(n^2) < O(2^n)$ | + | |
| + | 算法是解决特定问题求解步骤的描述。一个好的算法应该具备:**正确性、可读性、健壮性、高效率**。 | ||
| + | |||
| + | ==== 1. 算法效率度量:大O记号 ==== | ||
| + | |||
| + | 我们不计算具体的秒数(因为这取决于机器性能),而是计算**操作步骤数量随数据量 | ||
| + | |||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | .chart-container { | ||
| + | background: white; | ||
| + | padding: 20px; | ||
| + | border: 1px solid #eee; | ||
| + | border-radius: | ||
| + | max-width: 600px; | ||
| + | margin: 20px 0; | ||
| + | } | ||
| + | .bar-chart { | ||
| + | display: flex; | ||
| + | flex-direction: | ||
| + | gap: 10px; | ||
| + | } | ||
| + | .bar-row { | ||
| + | display: flex; | ||
| + | align-items: | ||
| + | font-size: 14px; | ||
| + | } | ||
| + | .bar-label { | ||
| + | width: 80px; | ||
| + | font-weight: | ||
| + | text-align: right; | ||
| + | padding-right: | ||
| + | } | ||
| + | .bar-track { | ||
| + | flex-grow: 1; | ||
| + | background: #f0f0f0; | ||
| + | height: 20px; | ||
| + | border-radius: | ||
| + | overflow: hidden; | ||
| + | position: relative; | ||
| + | } | ||
| + | .bar-fill { | ||
| + | height: 100%; | ||
| + | display: flex; | ||
| + | align-items: | ||
| + | padding-left: | ||
| + | color: white; | ||
| + | font-size: 12px; | ||
| + | transition: width 1s ease-out; | ||
| + | } | ||
| + | .bg-green { background-color: | ||
| + | .bg-blue { background-color: | ||
| + | .bg-orange { background-color: | ||
| + | .bg-red { background-color: | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | <div class=" | ||
| + | <h4 style=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | === 1.1 常见复杂度详解 === | ||
| + | |||
| + | * | ||
| + | <code c> | ||
| + | int n = 10000; | ||
| + | x = n + 1; // 无论n多大,这行只执行一次 | ||
| + | </ | ||
| + | * **$O(n)$ 线性阶**:一层循环。 | ||
| + | <code c> | ||
| + | for(int i=0; i<n; i++) { ... } | ||
| + | </ | ||
| + | * **$O(n^2)$ 平方阶**:双层嵌套循环。 | ||
| + | <code c> | ||
| + | for(int i=0; i<n; i++) { | ||
| + | for(int j=0; j<n; j++) { ... } | ||
| + | } | ||
| + | </ | ||
| + | * **$O(\log n)$ 对数阶**:每次循环,数据量都砍半(如二分查找)。 | ||
| + | <code c> | ||
| + | while(n > 1) { | ||
| + | n = n / 2; // 1024 -> 512 -> 256 ... 10次就到了 | ||
| + | } | ||
| + | </ | ||
| ===== 第三部分:五大常用算法思想详解 ===== | ===== 第三部分:五大常用算法思想详解 ===== | ||
| - | 这是绪论中最具实战意义的部分,以下结合图片内容进行深度解析。 | + | 这是算法的灵魂,掌握这些思想比背诵代码更重要。 |
| ==== 1. 穷举法 (Brute Force) ==== | ==== 1. 穷举法 (Brute Force) ==== | ||
| + | |||
| * | * | ||
| - | * | + | * |
| - | * | + | |
| - | * | + | |
| - | * | + | * |
| - | * | + | |
| - | ==== 2. 递推法与迭代法 ==== | + | ==== 2. 分治法 (Divide and Conquer) ==== |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | ==== 3. 分治法 (Divide and Conquer) ==== | + | |
| - | | + | * **适用场景**:问题可以拆解为多个独立的子问题,且子问题与原问题结构相同。 |
| - | * **三步走**: | + | * **典型应用**:归并排序 |
| - | * **分 (Divide)**:把大问题切成几个**独立的**小问题。 | + | |
| - | * **治 (Conquer)**:递归解决小问题。 | + | |
| - | * **合 (Combine)**:把小问题的结果拼起来。 | + | |
| - | * **案例**:**排序问题**。 | + | |
| - | * | + | |
| - | * | + | |
| - | ==== 4. 贪婪算法 | + | < |
| - | * | + | < |
| - | * **特点**:一旦选定,**不回溯**(不后悔)。 | + | < |
| - | * **案例**:**找零钱问题**。 | + | < |
| - | * *场景*:要找回 15 元,现有面值 11元、5元、1元。 | + | < |
| - | * *贪心策略*:优先选最大的。 | + | .dc-wrapper { |
| - | * | + | text-align: center; |
| - | * | + | padding: 15px; |
| - | * | + | background: #f0f4c3; |
| - | * **结果**:1张11元 + 4张1元 | + | border-radius: |
| - | * | + | border: 1px solid #dce775; |
| - | * | + | } |
| - | * *结论*:贪心算法**快**,但**不一定能得到全局最优解**(除非硬币面值设计得好,如 1, 5, 10)。 | + | .dc-block { |
| + | display: inline-block; | ||
| + | background: #8bc34a; | ||
| + | color: white; | ||
| + | padding: 8px 15px; | ||
| + | border-radius: | ||
| + | margin: 5px; | ||
| + | font-size: 12px; | ||
| + | box-shadow: 0 2px 4px rgba(0, | ||
| + | } | ||
| + | .dc-arrow { color: #555; font-size: 12px; margin: 5px 0; } | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | <span style=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ==== 3. 动态规划 | ||
| + | |||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * 求第 5 个数:$F(5) = F(4) + F(3)$ | ||
| + | * 求 $F(4)$ 时需要算 $F(3) + F(2)$。 | ||
| + | * | ||
| + | * **DP做法**:算完 $F(3)$ 就把它记在本子上,下次直接看本子。 | ||
| + | |||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | .dp-container { | ||
| + | display: flex; | ||
| + | gap: 20px; | ||
| + | justify-content: | ||
| + | background: #e3f2fd; | ||
| + | padding: 20px; | ||
| + | border-radius: | ||
| + | border: 1px solid #bbdefb; | ||
| + | } | ||
| + | .dp-box { | ||
| + | flex: 1; | ||
| + | background: white; | ||
| + | padding: 10px; | ||
| + | border-radius: | ||
| + | text-align: center; | ||
| + | } | ||
| + | .dp-title { font-weight: | ||
| + | .dp-table { | ||
| + | display: grid; | ||
| + | grid-template-columns: | ||
| + | gap: 2px; | ||
| + | background: #ccc; | ||
| + | padding: 2px; | ||
| + | margin-top: 10px; | ||
| + | } | ||
| + | .dp-cell { background: #fff; padding: 5px; font-size: 10px; } | ||
| + | .dp-cell.filled { background: #4caf50; color: white; } | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <span class=" | ||
| + | <div style=" | ||
| + | f(5) 需要算 f(4) 和 f(3)< | ||
| + | f(4) 需要算 f(3) 和 f(2)< | ||
| + | <span style=" | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <span class=" | ||
| + | <div style=" | ||
| + | 算过 f(3) 吗?< | ||
| + | 算过 -> <span style=" | ||
| + | 没算 -> 算出并填表 | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ==== 4. 贪心算法 (Greedy) ==== | ||
| + | |||
| + | * **核心**:**活在当下**。 | ||
| + | * **策略**:每一步都做出在当前看来最好的选择。它不从整体最优考虑,但在很多情况下(如最小生成树),局部最优能导致全局最优。 | ||
| + | | ||
| + | * 问题:找 | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * 6 >= 5,**给一张 5**。剩 1。 | ||
| + | * **给一张 1**。结束。 | ||
| + | * **局限**:如果纸币规格是 1, 3, 4,找 6 元。贪心会给 4+1+1 (3张),但最优解是 3+3 (2张)。此时贪心失效,需用 DP。 | ||
| + | |||
| + | ==== 5. 回溯法 (Backtracking) | ||
| + | |||
| + | | ||
| + | * **策略**:这是一种深度优先搜索 (DFS)。一条路走到黑,如果发现走不通(不满足条件),就**回溯**到上一个路口,换一条路继续走。 | ||
| + | | ||
| + | | ||
| + | |||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | .bt-maze { | ||
| + | position: relative; | ||
| + | width: 200px; | ||
| + | height: 120px; | ||
| + | background: #333; | ||
| + | margin: 0 auto; | ||
| + | border-radius: | ||
| + | overflow: hidden; | ||
| + | } | ||
| + | .bt-path { | ||
| + | position: absolute; | ||
| + | background: #fff; | ||
| + | transition: all 0.5s; | ||
| + | } | ||
| + | .p1 { top: 50px; left: 10px; width: 40px; height: 10px; } | ||
| + | .p2 { top: 20px; left: 40px; width: 10px; height: 40px; } | ||
| + | .p3 { top: 20px; left: 40px; width: 40px; height: 10px; background: #f44336; } | ||
| + | .p4 { top: 50px; left: 40px; width: 60px; height: 10px; } | ||
| + | .p5 { top: 50px; left: 90px; width: 10px; height: 40px; } | ||
| + | .p6 { top: 80px; left: 90px; width: 60px; height: 10px; background: #4caf50; } | ||
| + | .bt-label { | ||
| + | position: absolute; | ||
| + | color: white; | ||
| + | font-size: 10px; | ||
| + | padding: 2px; | ||
| + | } | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | <div style=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | </ | ||
| + | <p style=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| - | ==== 5. 动态规划 (Dynamic Programming) | + | ===== 总结:如何选择算法? ===== |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| - | * 求 `Fib(5)` 需要 `Fib(4)` 和 `Fib(3)`。 | + | |
| - | * 求 `Fib(4)` 需要 `Fib(3)` 和 `Fib(2)`。 | + | |
| - | * | + | |
| - | * | + | |
| - | * | + | |
| + | | 场景特点 | 推荐策略 | 核心思想 | | ||
| + | | 问题可拆分,子问题独立 | **分治法** | 大事化小 | | ||
| + | | 问题可拆分,子问题重叠 | **动态规划** | 拒绝健忘,查表 | | ||
| + | | 需要快速找到一个可行解 | **贪心算法** | 目光短浅,先拿再说 | | ||
| + | | 需要遍历所有解或路径 | **回溯法** | 不撞南墙不回头 | | ||
| + | | 没有任何规律 | **穷举法** | 暴力出奇迹 | | ||