This commit is contained in:
krahets 2023-07-01 22:39:28 +08:00
parent dbae108dac
commit 78810844f4
87 changed files with 4453 additions and 2776 deletions

View file

@ -1887,6 +1887,8 @@
@ -1916,7 +1918,21 @@
<li class="md-nav__item">
<a href="/chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="/chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1898,6 +1898,8 @@
@ -1927,7 +1929,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -15,7 +15,7 @@
<link rel="canonical" href="https://www.hello-algo.com/chapter_appendix/installation/">
<link rel="prev" href="../../chapter_dynamic_programming/intro_to_dynamic_programming/">
<link rel="prev" href="../../chapter_dynamic_programming/dp_problem_features/">
<link rel="next" href="../contribution/">
@ -1898,6 +1898,8 @@
@ -1927,7 +1929,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
@ -2389,7 +2405,7 @@
<nav class="md-footer__inner md-grid" aria-label="页脚" >
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-footer__link md-footer__link--prev" aria-label="上一页: 13.1. &amp;nbsp; 初探动态规划" rel="prev">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-footer__link md-footer__link--prev" aria-label="上一页: 13.2. &amp;nbsp; DP 问题特性New" rel="prev">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</div>
@ -2398,7 +2414,7 @@
上一页
</span>
<div class="md-ellipsis">
13.1. &nbsp; 初探动态规划
13.2. &nbsp; DP 问题特性New
</div>
</div>
</a>

View file

@ -1962,6 +1962,8 @@
@ -1991,7 +1993,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1962,6 +1962,8 @@
@ -1991,7 +1993,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
@ -2256,6 +2272,11 @@
<p class="admonition-title">“列表的出现大大提升了数组的实用性,但副作用是会造成部分内存空间浪费”,这里的空间浪费是指额外增加的变量如容量、长度、扩容倍数所占的内存吗?</p>
<p>这里的空间浪费主要有两方面含义:一方面,列表都会设定一个初始长度,我们不一定需要用这么多。另一方面,为了防止频繁扩容,扩容一般都会乘以一个系数,比如 <span class="arithmatex">\(\times 1.5\)</span> 。这样一来,也会出现很多空位,我们通常不能完全填满它们。</p>
</div>
<div class="admonition question">
<p class="admonition-title">在 Python 中初始化 <code>n = [1, 2, 3]</code> 后,这 3 个元素的地址是相连的,但是初始化 <code>m = [2, 1, 3]</code> 会发现它们每个元素的 id 并不是连续的,而是分别跟 <code>n</code> 中的相同。这些元素地址不连续,那么 <code>m</code> 还是数组吗?</p>
<p>假如把列表元素换成链表节点 <code>n = [n1, n2, n3, n4, n5]</code> ,通常情况下这五个节点对象也是被分散存储在内存各处的。然而,给定一个列表索引,我们仍然可以在 <span class="arithmatex">\(O(1)\)</span> 时间内获取到节点内存地址,从而访问到对应的节点。这是因为数组中存储的是节点的引用,而非节点本身。</p>
<p>与许多语言不同的是,在 Python 中数字也被包装为对象,列表中存储的不是数字本身,而是对数字的引用。因此,我们会发现两个数组中的相同数字拥有同一个 id ,并且这些数字的内存地址是无需连续的。</p>
</div>

View file

@ -1976,6 +1976,8 @@
@ -2005,7 +2007,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1910,6 +1910,8 @@
@ -1939,7 +1941,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1975,6 +1975,8 @@
@ -2004,7 +2006,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -2003,6 +2003,8 @@
@ -2032,7 +2034,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -2051,6 +2051,8 @@
@ -2080,7 +2082,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1910,6 +1910,8 @@
@ -1939,7 +1941,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1969,6 +1969,8 @@
@ -1998,7 +2000,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

File diff suppressed because it is too large Load diff

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
@ -2194,13 +2210,13 @@
<a href="intro_to_dynamic_programming/" class="md-footer__link md-footer__link--next" aria-label="下一页: 13.1. &amp;nbsp; 初探动态规划" rel="next">
<a href="intro_to_dynamic_programming/" class="md-footer__link md-footer__link--next" aria-label="下一页: 13.1. &amp;nbsp; 初探动态规划New" rel="next">
<div class="md-footer__title">
<span class="md-footer__direction">
下一页
</span>
<div class="md-ellipsis">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</div>
</div>
<div class="md-footer__button md-icon">

View file

@ -18,14 +18,14 @@
<link rel="prev" href="../">
<link rel="next" href="../../chapter_appendix/installation/">
<link rel="next" href="../dp_problem_features/">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.4.2, mkdocs-material-9.1.11">
<title>13.1.   初探动态规划 - Hello 算法</title>
<title>13.1.   初探动态规划New - Hello 算法</title>
@ -113,7 +113,7 @@
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</span>
</div>
@ -1900,6 +1900,8 @@
@ -1938,12 +1940,12 @@
<label class="md-nav__link md-nav__link--active" for="__toc">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
@ -1963,48 +1965,21 @@
<li class="md-nav__item">
<a href="#1311" class="md-nav__link">
13.1.1. &nbsp; 重叠子问题
13.1.1. &nbsp; 方法一:暴力搜索
</a>
<nav class="md-nav" aria-label="13.1.1. &nbsp; 重叠子问题">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
方法一:暴力搜索
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
方法二:记忆化搜索
</a>
</li>
<li class="md-nav__item">
<a href="#_3" class="md-nav__link">
方法三:动态规划
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#1312" class="md-nav__link">
13.1.2. &nbsp; 最优子结构
13.1.2. &nbsp; 方法二:记忆化搜索
</a>
</li>
<li class="md-nav__item">
<a href="#1313" class="md-nav__link">
13.1.3. &nbsp; 无后效性
13.1.3. &nbsp; 方法三:动态规划
</a>
</li>
@ -2018,6 +1993,20 @@
<li class="md-nav__item">
<a href="../dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
</ul>
</nav>
</li>
@ -2166,48 +2155,21 @@
<li class="md-nav__item">
<a href="#1311" class="md-nav__link">
13.1.1. &nbsp; 重叠子问题
13.1.1. &nbsp; 方法一:暴力搜索
</a>
<nav class="md-nav" aria-label="13.1.1. &nbsp; 重叠子问题">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
方法一:暴力搜索
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
方法二:记忆化搜索
</a>
</li>
<li class="md-nav__item">
<a href="#_3" class="md-nav__link">
方法三:动态规划
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#1312" class="md-nav__link">
13.1.2. &nbsp; 最优子结构
13.1.2. &nbsp; 方法二:记忆化搜索
</a>
</li>
<li class="md-nav__item">
<a href="#1313" class="md-nav__link">
13.1.3. &nbsp; 无后效性
13.1.3. &nbsp; 方法三:动态规划
</a>
</li>
@ -2236,17 +2198,13 @@
<h1 id="131">13.1. &nbsp; 初探动态规划<a class="headerlink" href="#131" title="Permanent link">&para;</a></h1>
<p>「动态规划 Dynamic Programming」是一种通过将复杂问题分解为更简单的子问题方式来求解问题的方法通常用来求解最优方案的相关问题例如寻找最短路径、最大利润、最少时间等。</p>
<p>然而,并非所有的最优化问题都适合用动态规划来解决。<strong>只有当问题具有重叠子问题、最优子结构、无后效性时,动态规划才能发挥出其优势</strong></p>
<p>在本节,我们先从几个经典例题入手,总览动态规划的主要特征,包括:</p>
<p>动态规划Dynamic Programming是一种用于解决复杂问题的优化算法它把一个问题分解为一系列更小的子问题并把子问题的解存储起来以供后续使用从而避免了重复计算提升了解题效率。</p>
<p>在本节中,我们先从一个动态规划经典例题入手,学习动态规划是如何高效地求解问题的,包括:</p>
<ol>
<li>如何使用回溯来暴力求解动态规划问题,其中为什么包含重叠子问题。</li>
<li>动态规划是如何通过引入“记忆化”来优化时间复杂度的,并给出从顶至底和从底至顶两种解法。</li>
<li>动态规划的常用术语,状态压缩的实现方式。</li>
<li>最优子结构在动态规划问题中的表现形式,动态规划与分治的区别是什么。</li>
<li>无后效性的含义,其对动态规划的意义是什么。</li>
<li>如何暴力求解动态规划问题,什么是重叠子问题。</li>
<li>如何向暴力搜索引入记忆化处理,从而优化时间复杂度。</li>
<li>从递归解法引出动态规划解法,以及如何优化空间复杂度。</li>
</ol>
<h2 id="1311">13.1.1. &nbsp; 重叠子问题<a class="headerlink" href="#1311" title="Permanent link">&para;</a></h2>
<div class="admonition question">
<p class="admonition-title">爬楼梯</p>
<p>给定一个共有 <span class="arithmatex">\(n\)</span> 阶的楼梯,你每步可以上 <span class="arithmatex">\(1\)</span> 阶或者 <span class="arithmatex">\(2\)</span> 阶,请问有多少种方案可以爬到楼顶。</p>
@ -2388,9 +2346,12 @@
</div>
</div>
</div>
<h3 id="_1">方法一:暴力搜索<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h3>
<p>然而,这道题并不是典型的回溯问题,而更适合从分治的角度进行解析:在分治算法中,原问题被分解为较小的子问题,通过组合子问题的解得到原问题的解。例如,归并排序将一个长数组从顶至底地划分为两个短数组,再从底至顶地将已排序的短数组进行排序。</p>
<p>对于本题,设爬到第 <span class="arithmatex">\(i\)</span> 阶共有 <span class="arithmatex">\(dp[i]\)</span> 种方案,那么 <span class="arithmatex">\(dp[i]\)</span> 就是原问题,其子问题包括 <span class="arithmatex">\(dp[i-1]\)</span> , <span class="arithmatex">\(dp[i-2]\)</span> , <span class="arithmatex">\(\cdots\)</span> , <span class="arithmatex">\(dp[2]\)</span> , <span class="arithmatex">\(dp[1]\)</span></p>
<h2 id="1311">13.1.1. &nbsp; 方法一:暴力搜索<a class="headerlink" href="#1311" title="Permanent link">&para;</a></h2>
<p>然而,爬楼梯并不是典型的回溯问题,更适合从分治的角度进行解析。在分治算法中,原问题被分解为较小的子问题,通过组合子问题的解得到原问题的解。例如,归并排序将一个长数组从顶至底地划分为两个短数组,再从底至顶地将已排序的短数组进行排序。</p>
<p>对于本题,设爬到第 <span class="arithmatex">\(i\)</span> 阶共有 <span class="arithmatex">\(dp[i]\)</span> 种方案,那么 <span class="arithmatex">\(dp[i]\)</span> 就是原问题,其子问题包括:</p>
<div class="arithmatex">\[
dp[i-1] , dp[i-2] , \cdots , dp[2] , dp[1]
\]</div>
<p>由于每轮只能上 <span class="arithmatex">\(1\)</span> 阶或 <span class="arithmatex">\(2\)</span> 阶,因此当我们站在第 <span class="arithmatex">\(i\)</span> 阶楼梯上时,上一轮只可能站在第 <span class="arithmatex">\(i - 1\)</span> 阶或第 <span class="arithmatex">\(i - 2\)</span> 阶上,换句话说,我们只能从第 <span class="arithmatex">\(i -1\)</span> 阶或第 <span class="arithmatex">\(i - 2\)</span> 阶前往第 <span class="arithmatex">\(i\)</span> 阶。因此,<strong>爬到第 <span class="arithmatex">\(i - 1\)</span> 阶的方案数加上爬到第 <span class="arithmatex">\(i - 2\)</span> 阶的方案数就等于爬到第 <span class="arithmatex">\(i\)</span> 阶的方案数</strong>,即:</p>
<div class="arithmatex">\[
dp[i] = dp[i-1] + dp[i-2]
@ -2399,7 +2360,7 @@ dp[i] = dp[i-1] + dp[i-2]
<p align="center"> Fig. 方案数量递推公式 </p>
<p>基于此递推公式,我们可以写出递归代码:以 <span class="arithmatex">\(dp[n]\)</span> 为起始点,<strong>从顶至底地将一个较大问题拆解为两个较小问题</strong>,直至到达最小子问题 <span class="arithmatex">\(dp[1]\)</span><span class="arithmatex">\(dp[2]\)</span> 时返回。其中,最小子问题的解是已知的,即爬到第 <span class="arithmatex">\(1\)</span> , <span class="arithmatex">\(2\)</span> 阶分别有 <span class="arithmatex">\(1\)</span> , <span class="arithmatex">\(2\)</span> 种方案。</p>
<p>虽然以下代码也属于深度优先搜索,但比标准回溯算法代码简洁很多,这体现了从分治角度考虑这道题的优势。</p>
<p>以下代码与回溯解法一样,都属于深度优先搜索,但它比回溯算法更加简洁,这体现了从分治角度考虑这道题的优势。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="2:11"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Java</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Python</label><label for="__tabbed_2_4">Go</label><label for="__tabbed_2_5">JavaScript</label><label for="__tabbed_2_6">TypeScript</label><label for="__tabbed_2_7">C</label><label for="__tabbed_2_8">C#</label><label for="__tabbed_2_9">Swift</label><label for="__tabbed_2_10">Zig</label><label for="__tabbed_2_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@ -2506,8 +2467,12 @@ dp[i] = dp[i-1] + dp[i-2]
<p align="center"> Fig. 爬楼梯对应递归树 </p>
<p>实际上,<strong>指数阶的时间复杂度是由于「重叠子问题」导致的</strong>。例如,问题 <span class="arithmatex">\(dp[9]\)</span> 被分解为子问题 <span class="arithmatex">\(dp[8]\)</span><span class="arithmatex">\(dp[7]\)</span> ,问题 <span class="arithmatex">\(dp[8]\)</span> 被分解为子问题 <span class="arithmatex">\(dp[7]\)</span><span class="arithmatex">\(dp[6]\)</span> ,两者都包含子问题 <span class="arithmatex">\(dp[7]\)</span> ,而子问题中又包含更小的重叠子问题,子子孙孙无穷尽也,绝大部分计算资源都浪费在这些重叠的问题上。</p>
<h3 id="_2">方法二:记忆化搜索<a class="headerlink" href="#_2" title="Permanent link">&para;</a></h3>
<p>为了提升算法效率,<strong>我们希望所有的重叠子问题只被计算一次</strong>。具体来说,考虑借助一个数组 <code>mem</code> 来记录每个子问题的解。当首次计算 <span class="arithmatex">\(dp[i]\)</span> 时,我们将其记录至 <code>mem[i]</code> ;当再次需要计算 <span class="arithmatex">\(dp[i]\)</span> 时,我们便可直接从 <code>mem[i]</code> 中获取结果,从而实现将重叠子问题剪枝。这种方法被称为“记忆化搜索”。</p>
<h2 id="1312">13.1.2. &nbsp; 方法二:记忆化搜索<a class="headerlink" href="#1312" title="Permanent link">&para;</a></h2>
<p>为了提升算法效率,<strong>我们希望所有的重叠子问题都只被计算一次</strong>。具体来说,考虑借助一个数组 <code>mem</code> 来记录每个子问题的解,并在搜索过程中这样做:</p>
<ul>
<li>当首次计算 <span class="arithmatex">\(dp[i]\)</span> 时,我们将其记录至 <code>mem[i]</code> ,以便之后使用;</li>
<li>当再次需要计算 <span class="arithmatex">\(dp[i]\)</span> 时,我们便可直接从 <code>mem[i]</code> 中获取结果,从而将重叠子问题剪枝;</li>
</ul>
<div class="tabbed-set tabbed-alternate" data-tabs="3:11"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Java</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Python</label><label for="__tabbed_3_4">Go</label><label for="__tabbed_3_5">JavaScript</label><label for="__tabbed_3_6">TypeScript</label><label for="__tabbed_3_7">C</label><label for="__tabbed_3_8">C#</label><label for="__tabbed_3_9">Swift</label><label for="__tabbed_3_10">Zig</label><label for="__tabbed_3_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@ -2631,13 +2596,13 @@ dp[i] = dp[i-1] + dp[i-2]
</div>
</div>
</div>
<p>观察下图,经过记忆化处理后,所有子问题都只需被计算一次,时间复杂度 <span class="arithmatex">\(O(n)\)</span> ,这是一个巨大的飞跃。实际上,如果不考虑递归带来的额外开销,记忆化搜索解法已经几乎等同于动态规划解法的时间效率。</p>
<p>观察下图,<strong>经过记忆化处理后,所有重叠子问题都只需被计算一次,时间复杂度被优化至 <span class="arithmatex">\(O(n)\)</span></strong> ,这是一个巨大的飞跃。实际上,如果不考虑递归带来的额外开销,记忆化搜索解法已经几乎等同于动态规划解法的时间效率。</p>
<p><img alt="记忆化搜索对应递归树" src="../intro_to_dynamic_programming.assets/climbing_stairs_dfs_memo_tree.png" /></p>
<p align="center"> Fig. 记忆化搜索对应递归树 </p>
<h3 id="_3">方法三:动态规划<a class="headerlink" href="#_3" title="Permanent link">&para;</a></h3>
<h2 id="1313">13.1.3. &nbsp; 方法三:动态规划<a class="headerlink" href="#1313" title="Permanent link">&para;</a></h2>
<p><strong>记忆化搜索是一种“从顶至底”的方法</strong>:我们从原问题(根节点)开始,递归地将较大子问题分解为较小子问题,直至解已知的最小子问题(叶节点);最终通过回溯将子问题的解逐层收集,得到原问题的解。</p>
<p><strong>我们也可以直接“从底至顶”进行求解</strong>:从最小子问题开始,迭代地求解较大子问题,直至得到原问题的解。这便是动态规划</p>
<p><strong>我们也可以直接“从底至顶”进行求解</strong>,得到标准的动态规划解法:从最小子问题开始,迭代地求解较大子问题,直至得到原问题的解。</p>
<p>由于没有回溯过程,动态规划可以直接基于循环实现。我们初始化一个数组 <code>dp</code> 来存储子问题的解,从最小子问题开始,逐步求解较大子问题。在以下代码中,数组 <code>dp</code> 起到了记忆化搜索中数组 <code>mem</code> 相同的记录作用。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="4:11"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><input id="__tabbed_4_5" name="__tabbed_4" type="radio" /><input id="__tabbed_4_6" name="__tabbed_4" type="radio" /><input id="__tabbed_4_7" name="__tabbed_4" type="radio" /><input id="__tabbed_4_8" name="__tabbed_4" type="radio" /><input id="__tabbed_4_9" name="__tabbed_4" type="radio" /><input id="__tabbed_4_10" name="__tabbed_4" type="radio" /><input id="__tabbed_4_11" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">Java</label><label for="__tabbed_4_2">C++</label><label for="__tabbed_4_3">Python</label><label for="__tabbed_4_4">Go</label><label for="__tabbed_4_5">JavaScript</label><label for="__tabbed_4_6">TypeScript</label><label for="__tabbed_4_7">C</label><label for="__tabbed_4_8">C#</label><label for="__tabbed_4_9">Swift</label><label for="__tabbed_4_10">Zig</label><label for="__tabbed_4_11">Dart</label></div>
<div class="tabbed-content">
@ -2726,16 +2691,16 @@ dp[i] = dp[i-1] + dp[i-2]
</div>
</div>
</div>
<p>与回溯算法一样,动态规划也使用“状态”概念来表示问题求解的某个特定阶段,每个状态都对应一个子问题以及相应的局部最优解。例如对于爬楼梯问题,状态定义为当前所在楼梯阶数。动态规划的常用术语包括:</p>
<p>与回溯算法一样,动态规划也使用“状态”概念来表示问题求解的某个特定阶段,每个状态都对应一个子问题以及相应的局部最优解。例如对于爬楼梯问题,状态定义为当前所在楼梯阶数。<strong>动态规划的常用术语包括</strong></p>
<ul>
<li><span class="arithmatex">\(dp\)</span> 数组称为「状态列表」,索引与状态逐个对应,每个元素对应一个子问题的解;</li>
<li><span class="arithmatex">\(dp\)</span> 数组称为「状态列表」,<span class="arithmatex">\(dp[i]\)</span> 代表第 <span class="arithmatex">\(i\)</span> 个状态的解;</li>
<li>将最简单子问题对应的状态(即第 <span class="arithmatex">\(1\)</span> , <span class="arithmatex">\(2\)</span> 阶楼梯)称为「初始状态」;</li>
<li>将递推公式 <span class="arithmatex">\(dp[i] = dp[i-1] + dp[i-2]\)</span> 称为「状态转移方程」;</li>
</ul>
<p><img alt="爬楼梯的动态规划过程" src="../intro_to_dynamic_programming.assets/climbing_stairs_dp.png" /></p>
<p align="center"> Fig. 爬楼梯的动态规划过程 </p>
<p>细心的你可能发现,由于 <span class="arithmatex">\(dp[i]\)</span> 只与 <span class="arithmatex">\(dp[i-1]\)</span><span class="arithmatex">\(dp[i-2]\)</span> 有关,因此我们无需使用一个数组 <code>dp</code> 来存储所有状态,而只需两个变量滚动前进即可。如以下代码所示,由于省去了数组 <code>dp</code> 占用的空间,因此空间复杂度从 <span class="arithmatex">\(O(n)\)</span> 降低至 <span class="arithmatex">\(O(1)\)</span></p>
<p>细心的你可能发现,<strong>由于 <span class="arithmatex">\(dp[i]\)</span> 只与 <span class="arithmatex">\(dp[i-1]\)</span><span class="arithmatex">\(dp[i-2]\)</span> 有关,因此我们无需使用一个数组 <code>dp</code> 来存储所有状态</strong>,而只需两个变量滚动前进即可。如以下代码所示,由于省去了数组 <code>dp</code> 占用的空间,因此空间复杂度从 <span class="arithmatex">\(O(n)\)</span> 降低至 <span class="arithmatex">\(O(1)\)</span></p>
<div class="tabbed-set tabbed-alternate" data-tabs="5:11"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><input id="__tabbed_5_3" name="__tabbed_5" type="radio" /><input id="__tabbed_5_4" name="__tabbed_5" type="radio" /><input id="__tabbed_5_5" name="__tabbed_5" type="radio" /><input id="__tabbed_5_6" name="__tabbed_5" type="radio" /><input id="__tabbed_5_7" name="__tabbed_5" type="radio" /><input id="__tabbed_5_8" name="__tabbed_5" type="radio" /><input id="__tabbed_5_9" name="__tabbed_5" type="radio" /><input id="__tabbed_5_10" name="__tabbed_5" type="radio" /><input id="__tabbed_5_11" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">Java</label><label for="__tabbed_5_2">C++</label><label for="__tabbed_5_3">Python</label><label for="__tabbed_5_4">Go</label><label for="__tabbed_5_5">JavaScript</label><label for="__tabbed_5_6">TypeScript</label><label for="__tabbed_5_7">C</label><label for="__tabbed_5_8">C#</label><label for="__tabbed_5_9">Swift</label><label for="__tabbed_5_10">Zig</label><label for="__tabbed_5_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@ -2813,333 +2778,7 @@ dp[i] = dp[i-1] + dp[i-2]
</div>
</div>
</div>
<p><strong>这种做法被称为「状态压缩」</strong>。在许多动态规划问题中,当前状态仅与前面有限个状态有关,不必保存所有的历史状态,这时我们可以通过状态压缩的技巧,只保留必要的状态,通过“降维”来节省内存空间。</p>
<h2 id="1312">13.1.2. &nbsp; 最优子结构<a class="headerlink" href="#1312" title="Permanent link">&para;</a></h2>
<p>爬楼梯问题很好地展示了重叠子问题。接下来,我们对题目稍作改动,使之更加适合展示最优子结构概念。</p>
<div class="admonition question">
<p class="admonition-title">爬楼梯最小代价</p>
<p>给定一个楼梯,你每步可以上 <span class="arithmatex">\(1\)</span> 阶或者 <span class="arithmatex">\(2\)</span> 阶,每一阶楼梯上都贴有一个非负整数,表示你在该台阶所需要付出的代价。给定一个非负整数数组 <span class="arithmatex">\(cost\)</span> ,其中 <span class="arithmatex">\(cost[i]\)</span> 表示在第 <span class="arithmatex">\(i\)</span> 个台阶需要付出的代价,<span class="arithmatex">\(cost[0]\)</span> 为地面起始点。请计算最少需要付出多少代价才能到达顶部?</p>
</div>
<p>如下图所示,若第 <span class="arithmatex">\(1\)</span> , <span class="arithmatex">\(2\)</span> , <span class="arithmatex">\(3\)</span> 阶的代价分别为 <span class="arithmatex">\(1\)</span> , <span class="arithmatex">\(10\)</span> , <span class="arithmatex">\(1\)</span> ,则从地面爬到第 <span class="arithmatex">\(3\)</span> 阶的最小代价为 <span class="arithmatex">\(2\)</span></p>
<p><img alt="爬到第 3 阶的最小代价" src="../intro_to_dynamic_programming.assets/min_cost_cs_example.png" /></p>
<p align="center"> Fig. 爬到第 3 阶的最小代价 </p>
<p><span class="arithmatex">\(dp[i]\)</span> 为爬到第 <span class="arithmatex">\(i\)</span> 阶累计付出的代价,由于第 <span class="arithmatex">\(i\)</span> 阶只可能从 <span class="arithmatex">\(i - 1\)</span> 阶或 <span class="arithmatex">\(i - 2\)</span> 阶走来,因此 <span class="arithmatex">\(dp[i]\)</span> 只可能等于 <span class="arithmatex">\(dp[i - 1] + cost[i]\)</span><span class="arithmatex">\(dp[i - 2] + cost[i]\)</span> 。为了尽可能减少代价,我们应该选择两者中较小的那一个,即:</p>
<div class="arithmatex">\[
dp[i] = \min(dp[i-1], dp[i-2]) + cost[i]
\]</div>
<p>这便可以引出「最优子结构」的含义:<strong>原问题的最优解是从子问题的最优解构建得来的</strong>。对于本题,我们从两个子问题最优解 <span class="arithmatex">\(dp[i-1]\)</span> , <span class="arithmatex">\(dp[i-2]\)</span> 中挑选出较优的那一个,并用它构建出原问题 <span class="arithmatex">\(dp[i]\)</span> 的最优解。</p>
<p>相较于分治算法问题,动态规划问题的解也是由其子问题的解构成的。不同的是,<strong>动态规划中子问题的解不仅揭示了问题的局部最优解,而且还通过特定的递推关系链接起来,共同构建出原问题的全局最优解</strong></p>
<p>那么,上道爬楼梯题目有没有最优子结构呢?它要求解的是方案数量,看似是一个计数问题,但如果换一种问法:求解最大方案数量。我们惊喜地发现,<strong>虽然题目修改前后是等价的,但最优子结构浮现出来了</strong>:第 <span class="arithmatex">\(n\)</span> 阶最大方案数量等于第 <span class="arithmatex">\(n-1\)</span> 阶和第 <span class="arithmatex">\(n-2\)</span> 阶最大方案数量之和。所以说,最优子结构的是一个比较宽泛的概念,在不同问题中会有不同的含义。</p>
<p>根据以上状态转移方程,以及初始状态 <span class="arithmatex">\(dp[1] = cost[1]\)</span> , <span class="arithmatex">\(dp[2] = cost[2]\)</span> ,我们可以得出动态规划解题代码。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="6:11"><input checked="checked" id="__tabbed_6_1" name="__tabbed_6" type="radio" /><input id="__tabbed_6_2" name="__tabbed_6" type="radio" /><input id="__tabbed_6_3" name="__tabbed_6" type="radio" /><input id="__tabbed_6_4" name="__tabbed_6" type="radio" /><input id="__tabbed_6_5" name="__tabbed_6" type="radio" /><input id="__tabbed_6_6" name="__tabbed_6" type="radio" /><input id="__tabbed_6_7" name="__tabbed_6" type="radio" /><input id="__tabbed_6_8" name="__tabbed_6" type="radio" /><input id="__tabbed_6_9" name="__tabbed_6" type="radio" /><input id="__tabbed_6_10" name="__tabbed_6" type="radio" /><input id="__tabbed_6_11" name="__tabbed_6" type="radio" /><div class="tabbed-labels"><label for="__tabbed_6_1">Java</label><label for="__tabbed_6_2">C++</label><label for="__tabbed_6_3">Python</label><label for="__tabbed_6_4">Go</label><label for="__tabbed_6_5">JavaScript</label><label for="__tabbed_6_6">TypeScript</label><label for="__tabbed_6_7">C</label><label for="__tabbed_6_8">C#</label><label for="__tabbed_6_9">Swift</label><label for="__tabbed_6_10">Zig</label><label for="__tabbed_6_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.java</span><pre><span></span><code><a id="__codelineno-55-1" name="__codelineno-55-1" href="#__codelineno-55-1"></a><span class="cm">/* 爬楼梯最小代价:动态规划 */</span>
<a id="__codelineno-55-2" name="__codelineno-55-2" href="#__codelineno-55-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">minCostClimbingStairsDP</span><span class="p">(</span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">cost</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-55-3" name="__codelineno-55-3" href="#__codelineno-55-3"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">.</span><span class="na">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-55-4" name="__codelineno-55-4" href="#__codelineno-55-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span>
<a id="__codelineno-55-5" name="__codelineno-55-5" href="#__codelineno-55-5"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="n">n</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-55-6" name="__codelineno-55-6" href="#__codelineno-55-6"></a><span class="w"> </span><span class="c1">// 初始化 dp 列表,用于存储子问题的解</span>
<a id="__codelineno-55-7" name="__codelineno-55-7" href="#__codelineno-55-7"></a><span class="w"> </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="o">[</span><span class="n">n</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-55-8" name="__codelineno-55-8" href="#__codelineno-55-8"></a><span class="w"> </span><span class="c1">// 初始状态:预设最小子问题的解</span>
<a id="__codelineno-55-9" name="__codelineno-55-9" href="#__codelineno-55-9"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-55-10" name="__codelineno-55-10" href="#__codelineno-55-10"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-55-11" name="__codelineno-55-11" href="#__codelineno-55-11"></a><span class="w"> </span><span class="c1">// 状态转移:从较小子问题逐步求解较大子问题</span>
<a id="__codelineno-55-12" name="__codelineno-55-12" href="#__codelineno-55-12"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-55-13" name="__codelineno-55-13" href="#__codelineno-55-13"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="na">min</span><span class="p">(</span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">2</span><span class="o">]</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-55-14" name="__codelineno-55-14" href="#__codelineno-55-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-55-15" name="__codelineno-55-15" href="#__codelineno-55-15"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">n</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-55-16" name="__codelineno-55-16" href="#__codelineno-55-16"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.cpp</span><pre><span></span><code><a id="__codelineno-56-1" name="__codelineno-56-1" href="#__codelineno-56-1"></a><span class="cm">/* 爬楼梯最小代价:动态规划 */</span>
<a id="__codelineno-56-2" name="__codelineno-56-2" href="#__codelineno-56-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">minCostClimbingStairsDP</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="n">cost</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-56-3" name="__codelineno-56-3" href="#__codelineno-56-3"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-56-4" name="__codelineno-56-4" href="#__codelineno-56-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span>
<a id="__codelineno-56-5" name="__codelineno-56-5" href="#__codelineno-56-5"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="n">n</span><span class="p">];</span>
<a id="__codelineno-56-6" name="__codelineno-56-6" href="#__codelineno-56-6"></a><span class="w"> </span><span class="c1">// 初始化 dp 列表,用于存储子问题的解</span>
<a id="__codelineno-56-7" name="__codelineno-56-7" href="#__codelineno-56-7"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">dp</span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<a id="__codelineno-56-8" name="__codelineno-56-8" href="#__codelineno-56-8"></a><span class="w"> </span><span class="c1">// 初始状态:预设最小子问题的解</span>
<a id="__codelineno-56-9" name="__codelineno-56-9" href="#__codelineno-56-9"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<a id="__codelineno-56-10" name="__codelineno-56-10" href="#__codelineno-56-10"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<a id="__codelineno-56-11" name="__codelineno-56-11" href="#__codelineno-56-11"></a><span class="w"> </span><span class="c1">// 状态转移:从较小子问题逐步求解较大子问题</span>
<a id="__codelineno-56-12" name="__codelineno-56-12" href="#__codelineno-56-12"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-56-13" name="__codelineno-56-13" href="#__codelineno-56-13"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">],</span><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">2</span><span class="p">])</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<a id="__codelineno-56-14" name="__codelineno-56-14" href="#__codelineno-56-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-56-15" name="__codelineno-56-15" href="#__codelineno-56-15"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">];</span>
<a id="__codelineno-56-16" name="__codelineno-56-16" href="#__codelineno-56-16"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.py</span><pre><span></span><code><a id="__codelineno-57-1" name="__codelineno-57-1" href="#__codelineno-57-1"></a><span class="k">def</span> <span class="nf">min_cost_climbing_stairs_dp</span><span class="p">(</span><span class="n">cost</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-57-2" name="__codelineno-57-2" href="#__codelineno-57-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;爬楼梯最小代价:动态规划&quot;&quot;&quot;</span>
<a id="__codelineno-57-3" name="__codelineno-57-3" href="#__codelineno-57-3"></a> <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">cost</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<a id="__codelineno-57-4" name="__codelineno-57-4" href="#__codelineno-57-4"></a> <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">or</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<a id="__codelineno-57-5" name="__codelineno-57-5" href="#__codelineno-57-5"></a> <span class="k">return</span> <span class="n">cost</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
<a id="__codelineno-57-6" name="__codelineno-57-6" href="#__codelineno-57-6"></a> <span class="c1"># 初始化 dp 列表,用于存储子问题的解</span>
<a id="__codelineno-57-7" name="__codelineno-57-7" href="#__codelineno-57-7"></a> <span class="n">dp</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-57-8" name="__codelineno-57-8" href="#__codelineno-57-8"></a> <span class="c1"># 初始状态:预设最小子问题的解</span>
<a id="__codelineno-57-9" name="__codelineno-57-9" href="#__codelineno-57-9"></a> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">cost</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">cost</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<a id="__codelineno-57-10" name="__codelineno-57-10" href="#__codelineno-57-10"></a> <span class="c1"># 状态转移:从较小子问题逐步求解较大子问题</span>
<a id="__codelineno-57-11" name="__codelineno-57-11" href="#__codelineno-57-11"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<a id="__codelineno-57-12" name="__codelineno-57-12" href="#__codelineno-57-12"></a> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">])</span> <span class="o">+</span> <span class="n">cost</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<a id="__codelineno-57-13" name="__codelineno-57-13" href="#__codelineno-57-13"></a> <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.go</span><pre><span></span><code><a id="__codelineno-58-1" name="__codelineno-58-1" href="#__codelineno-58-1"></a><span class="p">[</span><span class="nx">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="nx">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.js</span><pre><span></span><code><a id="__codelineno-59-1" name="__codelineno-59-1" href="#__codelineno-59-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.ts</span><pre><span></span><code><a id="__codelineno-60-1" name="__codelineno-60-1" href="#__codelineno-60-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.c</span><pre><span></span><code><a id="__codelineno-61-1" name="__codelineno-61-1" href="#__codelineno-61-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.cs</span><pre><span></span><code><a id="__codelineno-62-1" name="__codelineno-62-1" href="#__codelineno-62-1"></a><span class="na">[class]</span><span class="p">{</span><span class="n">min_cost_climbing_stairs_dp</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.swift</span><pre><span></span><code><a id="__codelineno-63-1" name="__codelineno-63-1" href="#__codelineno-63-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.zig</span><pre><span></span><code><a id="__codelineno-64-1" name="__codelineno-64-1" href="#__codelineno-64-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.dart</span><pre><span></span><code><a id="__codelineno-65-1" name="__codelineno-65-1" href="#__codelineno-65-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDP</span><span class="p">}</span>
</code></pre></div>
</div>
</div>
</div>
<p><img alt="爬楼梯最小代价的动态规划过程" src="../intro_to_dynamic_programming.assets/min_cost_cs_dp.png" /></p>
<p align="center"> Fig. 爬楼梯最小代价的动态规划过程 </p>
<p>这道题同样也可以进行状态压缩,将一维压缩至零维,使得空间复杂度从 <span class="arithmatex">\(O(n)\)</span> 降低至 <span class="arithmatex">\(O(1)\)</span></p>
<div class="tabbed-set tabbed-alternate" data-tabs="7:11"><input checked="checked" id="__tabbed_7_1" name="__tabbed_7" type="radio" /><input id="__tabbed_7_2" name="__tabbed_7" type="radio" /><input id="__tabbed_7_3" name="__tabbed_7" type="radio" /><input id="__tabbed_7_4" name="__tabbed_7" type="radio" /><input id="__tabbed_7_5" name="__tabbed_7" type="radio" /><input id="__tabbed_7_6" name="__tabbed_7" type="radio" /><input id="__tabbed_7_7" name="__tabbed_7" type="radio" /><input id="__tabbed_7_8" name="__tabbed_7" type="radio" /><input id="__tabbed_7_9" name="__tabbed_7" type="radio" /><input id="__tabbed_7_10" name="__tabbed_7" type="radio" /><input id="__tabbed_7_11" name="__tabbed_7" type="radio" /><div class="tabbed-labels"><label for="__tabbed_7_1">Java</label><label for="__tabbed_7_2">C++</label><label for="__tabbed_7_3">Python</label><label for="__tabbed_7_4">Go</label><label for="__tabbed_7_5">JavaScript</label><label for="__tabbed_7_6">TypeScript</label><label for="__tabbed_7_7">C</label><label for="__tabbed_7_8">C#</label><label for="__tabbed_7_9">Swift</label><label for="__tabbed_7_10">Zig</label><label for="__tabbed_7_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.java</span><pre><span></span><code><a id="__codelineno-66-1" name="__codelineno-66-1" href="#__codelineno-66-1"></a><span class="cm">/* 爬楼梯最小代价:状态压缩后的动态规划 */</span>
<a id="__codelineno-66-2" name="__codelineno-66-2" href="#__codelineno-66-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">minCostClimbingStairsDPComp</span><span class="p">(</span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">cost</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-66-3" name="__codelineno-66-3" href="#__codelineno-66-3"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">.</span><span class="na">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-66-4" name="__codelineno-66-4" href="#__codelineno-66-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span>
<a id="__codelineno-66-5" name="__codelineno-66-5" href="#__codelineno-66-5"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="n">n</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-66-6" name="__codelineno-66-6" href="#__codelineno-66-6"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-66-7" name="__codelineno-66-7" href="#__codelineno-66-7"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-66-8" name="__codelineno-66-8" href="#__codelineno-66-8"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
<a id="__codelineno-66-9" name="__codelineno-66-9" href="#__codelineno-66-9"></a><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="na">min</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">tmp</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">cost</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-66-10" name="__codelineno-66-10" href="#__codelineno-66-10"></a><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tmp</span><span class="p">;</span>
<a id="__codelineno-66-11" name="__codelineno-66-11" href="#__codelineno-66-11"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-66-12" name="__codelineno-66-12" href="#__codelineno-66-12"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
<a id="__codelineno-66-13" name="__codelineno-66-13" href="#__codelineno-66-13"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.cpp</span><pre><span></span><code><a id="__codelineno-67-1" name="__codelineno-67-1" href="#__codelineno-67-1"></a><span class="cm">/* 爬楼梯最小代价:状态压缩后的动态规划 */</span>
<a id="__codelineno-67-2" name="__codelineno-67-2" href="#__codelineno-67-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">minCostClimbingStairsDPComp</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="n">cost</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-67-3" name="__codelineno-67-3" href="#__codelineno-67-3"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-67-4" name="__codelineno-67-4" href="#__codelineno-67-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span>
<a id="__codelineno-67-5" name="__codelineno-67-5" href="#__codelineno-67-5"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="n">n</span><span class="p">];</span>
<a id="__codelineno-67-6" name="__codelineno-67-6" href="#__codelineno-67-6"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<a id="__codelineno-67-7" name="__codelineno-67-7" href="#__codelineno-67-7"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-67-8" name="__codelineno-67-8" href="#__codelineno-67-8"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
<a id="__codelineno-67-9" name="__codelineno-67-9" href="#__codelineno-67-9"></a><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">tmp</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">cost</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<a id="__codelineno-67-10" name="__codelineno-67-10" href="#__codelineno-67-10"></a><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tmp</span><span class="p">;</span>
<a id="__codelineno-67-11" name="__codelineno-67-11" href="#__codelineno-67-11"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-67-12" name="__codelineno-67-12" href="#__codelineno-67-12"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
<a id="__codelineno-67-13" name="__codelineno-67-13" href="#__codelineno-67-13"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.py</span><pre><span></span><code><a id="__codelineno-68-1" name="__codelineno-68-1" href="#__codelineno-68-1"></a><span class="k">def</span> <span class="nf">min_cost_climbing_stairs_dp_comp</span><span class="p">(</span><span class="n">cost</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-68-2" name="__codelineno-68-2" href="#__codelineno-68-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;爬楼梯最小代价:状态压缩后的动态规划&quot;&quot;&quot;</span>
<a id="__codelineno-68-3" name="__codelineno-68-3" href="#__codelineno-68-3"></a> <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">cost</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<a id="__codelineno-68-4" name="__codelineno-68-4" href="#__codelineno-68-4"></a> <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">or</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<a id="__codelineno-68-5" name="__codelineno-68-5" href="#__codelineno-68-5"></a> <span class="k">return</span> <span class="n">cost</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
<a id="__codelineno-68-6" name="__codelineno-68-6" href="#__codelineno-68-6"></a> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">cost</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">cost</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<a id="__codelineno-68-7" name="__codelineno-68-7" href="#__codelineno-68-7"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<a id="__codelineno-68-8" name="__codelineno-68-8" href="#__codelineno-68-8"></a> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="nb">min</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="o">+</span> <span class="n">cost</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<a id="__codelineno-68-9" name="__codelineno-68-9" href="#__codelineno-68-9"></a> <span class="k">return</span> <span class="n">b</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.go</span><pre><span></span><code><a id="__codelineno-69-1" name="__codelineno-69-1" href="#__codelineno-69-1"></a><span class="p">[</span><span class="nx">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="nx">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.js</span><pre><span></span><code><a id="__codelineno-70-1" name="__codelineno-70-1" href="#__codelineno-70-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.ts</span><pre><span></span><code><a id="__codelineno-71-1" name="__codelineno-71-1" href="#__codelineno-71-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.c</span><pre><span></span><code><a id="__codelineno-72-1" name="__codelineno-72-1" href="#__codelineno-72-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.cs</span><pre><span></span><code><a id="__codelineno-73-1" name="__codelineno-73-1" href="#__codelineno-73-1"></a><span class="na">[class]</span><span class="p">{</span><span class="n">min_cost_climbing_stairs_dp</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.swift</span><pre><span></span><code><a id="__codelineno-74-1" name="__codelineno-74-1" href="#__codelineno-74-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.zig</span><pre><span></span><code><a id="__codelineno-75-1" name="__codelineno-75-1" href="#__codelineno-75-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">min_cost_climbing_stairs_dp.dart</span><pre><span></span><code><a id="__codelineno-76-1" name="__codelineno-76-1" href="#__codelineno-76-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">minCostClimbingStairsDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
</div>
</div>
<h2 id="1313">13.1.3. &nbsp; 无后效性<a class="headerlink" href="#1313" title="Permanent link">&para;</a></h2>
<p>除了重叠子问题和最优子结构以外,「无后效性」也是动态规划能够有效解决问题的重要特性之一。我们先来看下无后效性定义:<strong>给定一个确定的状态,它的未来发展只与当前状态有关,而与当前状态过去所经历过的所有状态无关</strong></p>
<p>以爬楼梯问题为例,给定状态 <span class="arithmatex">\(i\)</span> ,它会发展出状态 <span class="arithmatex">\(i+1\)</span> 和状态 <span class="arithmatex">\(i+2\)</span> ,分别对应跳 <span class="arithmatex">\(1\)</span> 步和跳 <span class="arithmatex">\(2\)</span> 步。在做出这两种选择时,我们无需考虑状态 <span class="arithmatex">\(i\)</span> 之前的状态,即它们对状态 <span class="arithmatex">\(i\)</span> 的未来没有影响。</p>
<p>然而,如果我们向爬楼梯问题添加一个约束,情况就不一样了。</p>
<div class="admonition question">
<p class="admonition-title">带约束爬楼梯</p>
<p>给定一个共有 <span class="arithmatex">\(n\)</span> 阶的楼梯,你每步可以上 <span class="arithmatex">\(1\)</span> 阶或者 <span class="arithmatex">\(2\)</span> 阶,<strong>但不能连续两轮跳 <span class="arithmatex">\(1\)</span></strong>,请问有多少种方案可以爬到楼顶。</p>
</div>
<p>例如,爬上第 <span class="arithmatex">\(3\)</span> 阶仅剩 <span class="arithmatex">\(2\)</span> 种可行方案,其中连续三次跳 <span class="arithmatex">\(1\)</span> 阶的方案不满足约束条件,因此被舍弃。</p>
<p><img alt="带约束爬到第 3 阶的方案数量" src="../intro_to_dynamic_programming.assets/climbing_stairs_constraint_example.png" /></p>
<p align="center"> Fig. 带约束爬到第 3 阶的方案数量 </p>
<p>在该问题中,<strong>下一步选择不能由当前状态(当前楼梯阶数)独立决定,还和前一个状态(上轮楼梯阶数)有关</strong>。如果上一轮是跳 <span class="arithmatex">\(1\)</span> 阶上来的,那么下一轮就必须跳 <span class="arithmatex">\(2\)</span> 阶。</p>
<p>不难发现,此问题已不满足无后效性,状态转移方程 <span class="arithmatex">\(dp[i] = dp[i-1] + dp[i-2]\)</span> 也失效了,因为 <span class="arithmatex">\(dp[i-1]\)</span> 代表本轮跳 <span class="arithmatex">\(1\)</span> 阶,但其中包含了许多“上一轮跳 <span class="arithmatex">\(1\)</span> 阶上来的”方案,而为了满足约束,我们不能将 <span class="arithmatex">\(dp[i-1]\)</span> 直接计入 <span class="arithmatex">\(dp[i]\)</span> 中。</p>
<p>为了解决该问题,我们需要扩展状态定义:<strong>状态 <span class="arithmatex">\([i, j]\)</span> 表示处在第 <span class="arithmatex">\(i\)</span> 阶、并且上一轮跳了 <span class="arithmatex">\(j\)</span></strong>,其中 <span class="arithmatex">\(j \in \{1, 2\}\)</span> 。此状态定义有效地区分了上一轮跳了 <span class="arithmatex">\(1\)</span> 阶还是 <span class="arithmatex">\(2\)</span> 阶,我们可以据此来决定下一步该怎么跳:</p>
<ul>
<li><span class="arithmatex">\(j\)</span> 等于 <span class="arithmatex">\(1\)</span> ,即上一轮跳了 <span class="arithmatex">\(1\)</span> 阶时,这一轮只能选择跳 <span class="arithmatex">\(2\)</span> 阶;</li>
<li><span class="arithmatex">\(j\)</span> 等于 <span class="arithmatex">\(2\)</span> ,即上一轮跳了 <span class="arithmatex">\(2\)</span> 阶时,这一轮可选择跳 <span class="arithmatex">\(1\)</span> 阶或跳 <span class="arithmatex">\(2\)</span> 阶;</li>
</ul>
<p>在该定义下,<span class="arithmatex">\(dp[i, j]\)</span> 表示状态 <span class="arithmatex">\([i, j]\)</span> 对应的方案数。由此,我们便能推导出以下的状态转移方程:</p>
<div class="arithmatex">\[
\begin{cases}
dp[i, 1] = dp[i-1, 2] \\
dp[i, 2] = dp[i-2, 1] + dp[i-2, 2]
\end{cases}
\]</div>
<p><img alt="考虑约束下的递推关系" src="../intro_to_dynamic_programming.assets/climbing_stairs_constraint_state_transfer.png" /></p>
<p align="center"> Fig. 考虑约束下的递推关系 </p>
<p>最终,返回 <span class="arithmatex">\(dp[n, 1] + dp[n, 2]\)</span> 即可,两者之和代表爬到第 <span class="arithmatex">\(n\)</span> 阶的方案总数。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="8:11"><input checked="checked" id="__tabbed_8_1" name="__tabbed_8" type="radio" /><input id="__tabbed_8_2" name="__tabbed_8" type="radio" /><input id="__tabbed_8_3" name="__tabbed_8" type="radio" /><input id="__tabbed_8_4" name="__tabbed_8" type="radio" /><input id="__tabbed_8_5" name="__tabbed_8" type="radio" /><input id="__tabbed_8_6" name="__tabbed_8" type="radio" /><input id="__tabbed_8_7" name="__tabbed_8" type="radio" /><input id="__tabbed_8_8" name="__tabbed_8" type="radio" /><input id="__tabbed_8_9" name="__tabbed_8" type="radio" /><input id="__tabbed_8_10" name="__tabbed_8" type="radio" /><input id="__tabbed_8_11" name="__tabbed_8" type="radio" /><div class="tabbed-labels"><label for="__tabbed_8_1">Java</label><label for="__tabbed_8_2">C++</label><label for="__tabbed_8_3">Python</label><label for="__tabbed_8_4">Go</label><label for="__tabbed_8_5">JavaScript</label><label for="__tabbed_8_6">TypeScript</label><label for="__tabbed_8_7">C</label><label for="__tabbed_8_8">C#</label><label for="__tabbed_8_9">Swift</label><label for="__tabbed_8_10">Zig</label><label for="__tabbed_8_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.java</span><pre><span></span><code><a id="__codelineno-77-1" name="__codelineno-77-1" href="#__codelineno-77-1"></a><span class="cm">/* 带约束爬楼梯:动态规划 */</span>
<a id="__codelineno-77-2" name="__codelineno-77-2" href="#__codelineno-77-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">climbingStairsConstraintDP</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-77-3" name="__codelineno-77-3" href="#__codelineno-77-3"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-77-4" name="__codelineno-77-4" href="#__codelineno-77-4"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">n</span><span class="p">;</span>
<a id="__codelineno-77-5" name="__codelineno-77-5" href="#__codelineno-77-5"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-77-6" name="__codelineno-77-6" href="#__codelineno-77-6"></a><span class="w"> </span><span class="c1">// 初始化 dp 列表,用于存储子问题的解</span>
<a id="__codelineno-77-7" name="__codelineno-77-7" href="#__codelineno-77-7"></a><span class="w"> </span><span class="kt">int</span><span class="o">[][]</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="o">[</span><span class="n">n</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="o">][</span><span class="mi">3</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-77-8" name="__codelineno-77-8" href="#__codelineno-77-8"></a><span class="w"> </span><span class="c1">// 初始状态:预设最小子问题的解</span>
<a id="__codelineno-77-9" name="__codelineno-77-9" href="#__codelineno-77-9"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="mi">1</span><span class="o">][</span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-77-10" name="__codelineno-77-10" href="#__codelineno-77-10"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="mi">1</span><span class="o">][</span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-77-11" name="__codelineno-77-11" href="#__codelineno-77-11"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="mi">2</span><span class="o">][</span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-77-12" name="__codelineno-77-12" href="#__codelineno-77-12"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="mi">2</span><span class="o">][</span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-77-13" name="__codelineno-77-13" href="#__codelineno-77-13"></a><span class="w"> </span><span class="c1">// 状态转移:从较小子问题逐步求解较大子问题</span>
<a id="__codelineno-77-14" name="__codelineno-77-14" href="#__codelineno-77-14"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-77-15" name="__codelineno-77-15" href="#__codelineno-77-15"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="o">][</span><span class="mi">2</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-77-16" name="__codelineno-77-16" href="#__codelineno-77-16"></a><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">2</span><span class="o">][</span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">2</span><span class="o">][</span><span class="mi">2</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-77-17" name="__codelineno-77-17" href="#__codelineno-77-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-77-18" name="__codelineno-77-18" href="#__codelineno-77-18"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">n</span><span class="o">][</span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">n</span><span class="o">][</span><span class="mi">2</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-77-19" name="__codelineno-77-19" href="#__codelineno-77-19"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.cpp</span><pre><span></span><code><a id="__codelineno-78-1" name="__codelineno-78-1" href="#__codelineno-78-1"></a><span class="cm">/* 带约束爬楼梯:动态规划 */</span>
<a id="__codelineno-78-2" name="__codelineno-78-2" href="#__codelineno-78-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">climbingStairsConstraintDP</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-78-3" name="__codelineno-78-3" href="#__codelineno-78-3"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-78-4" name="__codelineno-78-4" href="#__codelineno-78-4"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">n</span><span class="p">;</span>
<a id="__codelineno-78-5" name="__codelineno-78-5" href="#__codelineno-78-5"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-78-6" name="__codelineno-78-6" href="#__codelineno-78-6"></a><span class="w"> </span><span class="c1">// 初始化 dp 列表,用于存储子问题的解</span>
<a id="__codelineno-78-7" name="__codelineno-78-7" href="#__codelineno-78-7"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="n">dp</span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">));</span>
<a id="__codelineno-78-8" name="__codelineno-78-8" href="#__codelineno-78-8"></a><span class="w"> </span><span class="c1">// 初始状态:预设最小子问题的解</span>
<a id="__codelineno-78-9" name="__codelineno-78-9" href="#__codelineno-78-9"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-78-10" name="__codelineno-78-10" href="#__codelineno-78-10"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-78-11" name="__codelineno-78-11" href="#__codelineno-78-11"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-78-12" name="__codelineno-78-12" href="#__codelineno-78-12"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-78-13" name="__codelineno-78-13" href="#__codelineno-78-13"></a><span class="w"> </span><span class="c1">// 状态转移:从较小子问题逐步求解较大子问题</span>
<a id="__codelineno-78-14" name="__codelineno-78-14" href="#__codelineno-78-14"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-78-15" name="__codelineno-78-15" href="#__codelineno-78-15"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span>
<a id="__codelineno-78-16" name="__codelineno-78-16" href="#__codelineno-78-16"></a><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">2</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span>
<a id="__codelineno-78-17" name="__codelineno-78-17" href="#__codelineno-78-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-78-18" name="__codelineno-78-18" href="#__codelineno-78-18"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span>
<a id="__codelineno-78-19" name="__codelineno-78-19" href="#__codelineno-78-19"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.py</span><pre><span></span><code><a id="__codelineno-79-1" name="__codelineno-79-1" href="#__codelineno-79-1"></a><span class="k">def</span> <span class="nf">climbing_stairs_constraint_dp</span><span class="p">(</span><span class="n">n</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-79-2" name="__codelineno-79-2" href="#__codelineno-79-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;带约束爬楼梯:动态规划&quot;&quot;&quot;</span>
<a id="__codelineno-79-3" name="__codelineno-79-3" href="#__codelineno-79-3"></a> <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">or</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<a id="__codelineno-79-4" name="__codelineno-79-4" href="#__codelineno-79-4"></a> <span class="k">return</span> <span class="n">n</span>
<a id="__codelineno-79-5" name="__codelineno-79-5" href="#__codelineno-79-5"></a> <span class="c1"># 初始化 dp 列表,用于存储子问题的解</span>
<a id="__codelineno-79-6" name="__codelineno-79-6" href="#__codelineno-79-6"></a> <span class="n">dp</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">3</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>
<a id="__codelineno-79-7" name="__codelineno-79-7" href="#__codelineno-79-7"></a> <span class="c1"># 初始状态:预设最小子问题的解</span>
<a id="__codelineno-79-8" name="__codelineno-79-8" href="#__codelineno-79-8"></a> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span>
<a id="__codelineno-79-9" name="__codelineno-79-9" href="#__codelineno-79-9"></a> <span class="n">dp</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<a id="__codelineno-79-10" name="__codelineno-79-10" href="#__codelineno-79-10"></a> <span class="c1"># 状态转移:从较小子问题逐步求解较大子问题</span>
<a id="__codelineno-79-11" name="__codelineno-79-11" href="#__codelineno-79-11"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<a id="__codelineno-79-12" name="__codelineno-79-12" href="#__codelineno-79-12"></a> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
<a id="__codelineno-79-13" name="__codelineno-79-13" href="#__codelineno-79-13"></a> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
<a id="__codelineno-79-14" name="__codelineno-79-14" href="#__codelineno-79-14"></a> <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.go</span><pre><span></span><code><a id="__codelineno-80-1" name="__codelineno-80-1" href="#__codelineno-80-1"></a><span class="p">[</span><span class="nx">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="nx">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.js</span><pre><span></span><code><a id="__codelineno-81-1" name="__codelineno-81-1" href="#__codelineno-81-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.ts</span><pre><span></span><code><a id="__codelineno-82-1" name="__codelineno-82-1" href="#__codelineno-82-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.c</span><pre><span></span><code><a id="__codelineno-83-1" name="__codelineno-83-1" href="#__codelineno-83-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.cs</span><pre><span></span><code><a id="__codelineno-84-1" name="__codelineno-84-1" href="#__codelineno-84-1"></a><span class="na">[class]</span><span class="p">{</span><span class="n">climbing_stairs_constraint_dp</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.swift</span><pre><span></span><code><a id="__codelineno-85-1" name="__codelineno-85-1" href="#__codelineno-85-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="n">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.zig</span><pre><span></span><code><a id="__codelineno-86-1" name="__codelineno-86-1" href="#__codelineno-86-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">climbing_stairs_constraint_dp.dart</span><pre><span></span><code><a id="__codelineno-87-1" name="__codelineno-87-1" href="#__codelineno-87-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">climbingStairsConstraintDP</span><span class="p">}</span>
</code></pre></div>
</div>
</div>
</div>
<p>在上面的案例中,由于仅需多考虑前面一个状态,我们仍然可以通过扩展状态定义,使得问题恢复无后效性。然而,许多问题具有非常严重的“有后效性”,例如:</p>
<div class="admonition question">
<p class="admonition-title">爬楼梯与障碍生成</p>
<p>给定一个共有 <span class="arithmatex">\(n\)</span> 阶的楼梯,你每步可以上 <span class="arithmatex">\(1\)</span> 阶或者 <span class="arithmatex">\(2\)</span> 阶。<strong>规定当爬到第 <span class="arithmatex">\(i\)</span> 阶时,系统自动会给第 <span class="arithmatex">\(2i\)</span> 阶上放上障碍物,之后所有轮都不允许跳到第 <span class="arithmatex">\(2i\)</span> 阶上</strong>。例如,前两轮分别跳到了第 <span class="arithmatex">\(2, 3\)</span> 阶上,则之后就不能跳到第 <span class="arithmatex">\(4, 6\)</span> 阶上。请问有多少种方案可以爬到楼顶。</p>
</div>
<p>在这个问题中,下次跳跃依赖于过去所有的状态,因为每一次跳跃都会在更高的阶梯上设置障碍,并影响未来的跳跃。对于这类问题,动态规划往往难以解决,或是因为计算复杂度过高而难以应用。</p>
<p>实际上,许多组合优化问题(例如著名的旅行商问题)都不满足无后效性。对于这类问题,我们通常会选择使用其他方法,例如启发式搜索、遗传算法、强化学习等,从而降低时间复杂度,在有限时间内得到能够接受的局部最优解。</p>
<p><strong>我们将这种空间优化技巧称为「状态压缩」</strong>。在许多动态规划问题中,当前状态仅与前面有限个状态有关,不必保存所有的历史状态,这时我们可以应用状态压缩,只保留必要的状态,通过“降维”来节省内存空间。</p>
@ -3233,13 +2872,13 @@ dp[i, 2] = dp[i-2, 1] + dp[i-2, 2]
<a href="../../chapter_appendix/installation/" class="md-footer__link md-footer__link--next" aria-label="下一页: 14.1. &amp;nbsp; 编程环境安装" rel="next">
<a href="../dp_problem_features/" class="md-footer__link md-footer__link--next" aria-label="下一页: 13.2. &amp;nbsp; DP 问题特性New" rel="next">
<div class="md-footer__title">
<span class="md-footer__direction">
下一页
</span>
<div class="md-ellipsis">
14.1. &nbsp; 编程环境安装
13.2. &nbsp; DP 问题特性New
</div>
</div>
<div class="md-footer__button md-icon">

View file

@ -1982,6 +1982,8 @@
@ -2011,7 +2013,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1988,6 +1988,8 @@
@ -2017,7 +2019,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1962,6 +1962,8 @@
@ -1991,7 +1993,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1968,6 +1968,8 @@
@ -1997,7 +1999,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
@ -2780,7 +2796,105 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">hash_map_chaining.swift</span><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{</span><span class="n">HashMapChaining</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{}</span>
<div class="highlight"><span class="filename">hash_map_chaining.swift</span><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="cm">/* 链式地址哈希表 */</span>
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="kd">class</span> <span class="nc">HashMapChaining</span> <span class="p">{</span>
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a> <span class="kd">var</span> <span class="nv">size</span><span class="p">:</span> <span class="nb">Int</span> <span class="c1">// 键值对数量</span>
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a> <span class="kd">var</span> <span class="nv">capacity</span><span class="p">:</span> <span class="nb">Int</span> <span class="c1">// 哈希表容量</span>
<a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a> <span class="kd">var</span> <span class="nv">loadThres</span><span class="p">:</span> <span class="nb">Double</span> <span class="c1">// 触发扩容的负载因子阈值</span>
<a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a> <span class="kd">var</span> <span class="nv">extendRatio</span><span class="p">:</span> <span class="nb">Int</span> <span class="c1">// 扩容倍数</span>
<a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a> <span class="kd">var</span> <span class="nv">buckets</span><span class="p">:</span> <span class="p">[[</span><span class="n">Pair</span><span class="p">]]</span> <span class="c1">// 桶数组</span>
<a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a>
<a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a> <span class="cm">/* 构造方法 */</span>
<a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a> <span class="kd">init</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a> <span class="n">size</span> <span class="p">=</span> <span class="mi">0</span>
<a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a> <span class="n">capacity</span> <span class="p">=</span> <span class="mi">4</span>
<a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a> <span class="n">loadThres</span> <span class="p">=</span> <span class="mi">2</span> <span class="o">/</span> <span class="mi">3</span>
<a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a> <span class="n">extendRatio</span> <span class="p">=</span> <span class="mi">2</span>
<a id="__codelineno-8-15" name="__codelineno-8-15" href="#__codelineno-8-15"></a> <span class="n">buckets</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="p">[],</span> <span class="bp">count</span><span class="p">:</span> <span class="n">capacity</span><span class="p">)</span>
<a id="__codelineno-8-16" name="__codelineno-8-16" href="#__codelineno-8-16"></a> <span class="p">}</span>
<a id="__codelineno-8-17" name="__codelineno-8-17" href="#__codelineno-8-17"></a>
<a id="__codelineno-8-18" name="__codelineno-8-18" href="#__codelineno-8-18"></a> <span class="cm">/* 哈希函数 */</span>
<a id="__codelineno-8-19" name="__codelineno-8-19" href="#__codelineno-8-19"></a> <span class="kd">func</span> <span class="nf">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-8-20" name="__codelineno-8-20" href="#__codelineno-8-20"></a> <span class="n">key</span> <span class="o">%</span> <span class="n">capacity</span>
<a id="__codelineno-8-21" name="__codelineno-8-21" href="#__codelineno-8-21"></a> <span class="p">}</span>
<a id="__codelineno-8-22" name="__codelineno-8-22" href="#__codelineno-8-22"></a>
<a id="__codelineno-8-23" name="__codelineno-8-23" href="#__codelineno-8-23"></a> <span class="cm">/* 负载因子 */</span>
<a id="__codelineno-8-24" name="__codelineno-8-24" href="#__codelineno-8-24"></a> <span class="kd">func</span> <span class="nf">loadFactor</span><span class="p">()</span> <span class="p">-&gt;</span> <span class="nb">Double</span> <span class="p">{</span>
<a id="__codelineno-8-25" name="__codelineno-8-25" href="#__codelineno-8-25"></a> <span class="nb">Double</span><span class="p">(</span><span class="n">size</span> <span class="o">/</span> <span class="n">capacity</span><span class="p">)</span>
<a id="__codelineno-8-26" name="__codelineno-8-26" href="#__codelineno-8-26"></a> <span class="p">}</span>
<a id="__codelineno-8-27" name="__codelineno-8-27" href="#__codelineno-8-27"></a>
<a id="__codelineno-8-28" name="__codelineno-8-28" href="#__codelineno-8-28"></a> <span class="cm">/* 查询操作 */</span>
<a id="__codelineno-8-29" name="__codelineno-8-29" href="#__codelineno-8-29"></a> <span class="kd">func</span> <span class="nf">get</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">String</span><span class="p">?</span> <span class="p">{</span>
<a id="__codelineno-8-30" name="__codelineno-8-30" href="#__codelineno-8-30"></a> <span class="kd">let</span> <span class="nv">index</span> <span class="p">=</span> <span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
<a id="__codelineno-8-31" name="__codelineno-8-31" href="#__codelineno-8-31"></a> <span class="kd">let</span> <span class="nv">bucket</span> <span class="p">=</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
<a id="__codelineno-8-32" name="__codelineno-8-32" href="#__codelineno-8-32"></a> <span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-8-33" name="__codelineno-8-33" href="#__codelineno-8-33"></a> <span class="k">for</span> <span class="n">pair</span> <span class="k">in</span> <span class="n">bucket</span> <span class="p">{</span>
<a id="__codelineno-8-34" name="__codelineno-8-34" href="#__codelineno-8-34"></a> <span class="k">if</span> <span class="n">pair</span><span class="p">.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span> <span class="p">{</span>
<a id="__codelineno-8-35" name="__codelineno-8-35" href="#__codelineno-8-35"></a> <span class="k">return</span> <span class="n">pair</span><span class="p">.</span><span class="n">val</span>
<a id="__codelineno-8-36" name="__codelineno-8-36" href="#__codelineno-8-36"></a> <span class="p">}</span>
<a id="__codelineno-8-37" name="__codelineno-8-37" href="#__codelineno-8-37"></a> <span class="p">}</span>
<a id="__codelineno-8-38" name="__codelineno-8-38" href="#__codelineno-8-38"></a> <span class="c1">// 若未找到 key 则返回 nil</span>
<a id="__codelineno-8-39" name="__codelineno-8-39" href="#__codelineno-8-39"></a> <span class="k">return</span> <span class="kc">nil</span>
<a id="__codelineno-8-40" name="__codelineno-8-40" href="#__codelineno-8-40"></a> <span class="p">}</span>
<a id="__codelineno-8-41" name="__codelineno-8-41" href="#__codelineno-8-41"></a>
<a id="__codelineno-8-42" name="__codelineno-8-42" href="#__codelineno-8-42"></a> <span class="cm">/* 添加操作 */</span>
<a id="__codelineno-8-43" name="__codelineno-8-43" href="#__codelineno-8-43"></a> <span class="kd">func</span> <span class="nf">put</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="nb">String</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-8-44" name="__codelineno-8-44" href="#__codelineno-8-44"></a> <span class="c1">// 当负载因子超过阈值时,执行扩容</span>
<a id="__codelineno-8-45" name="__codelineno-8-45" href="#__codelineno-8-45"></a> <span class="k">if</span> <span class="n">loadFactor</span><span class="p">()</span> <span class="o">&gt;</span> <span class="n">loadThres</span> <span class="p">{</span>
<a id="__codelineno-8-46" name="__codelineno-8-46" href="#__codelineno-8-46"></a> <span class="bp">extend</span><span class="p">()</span>
<a id="__codelineno-8-47" name="__codelineno-8-47" href="#__codelineno-8-47"></a> <span class="p">}</span>
<a id="__codelineno-8-48" name="__codelineno-8-48" href="#__codelineno-8-48"></a> <span class="kd">let</span> <span class="nv">index</span> <span class="p">=</span> <span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
<a id="__codelineno-8-49" name="__codelineno-8-49" href="#__codelineno-8-49"></a> <span class="kd">let</span> <span class="nv">bucket</span> <span class="p">=</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
<a id="__codelineno-8-50" name="__codelineno-8-50" href="#__codelineno-8-50"></a> <span class="c1">// 遍历桶,若遇到指定 key ,则更新对应 val 并返回</span>
<a id="__codelineno-8-51" name="__codelineno-8-51" href="#__codelineno-8-51"></a> <span class="k">for</span> <span class="n">pair</span> <span class="k">in</span> <span class="n">bucket</span> <span class="p">{</span>
<a id="__codelineno-8-52" name="__codelineno-8-52" href="#__codelineno-8-52"></a> <span class="k">if</span> <span class="n">pair</span><span class="p">.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span> <span class="p">{</span>
<a id="__codelineno-8-53" name="__codelineno-8-53" href="#__codelineno-8-53"></a> <span class="n">pair</span><span class="p">.</span><span class="n">val</span> <span class="p">=</span> <span class="n">val</span>
<a id="__codelineno-8-54" name="__codelineno-8-54" href="#__codelineno-8-54"></a> <span class="k">return</span>
<a id="__codelineno-8-55" name="__codelineno-8-55" href="#__codelineno-8-55"></a> <span class="p">}</span>
<a id="__codelineno-8-56" name="__codelineno-8-56" href="#__codelineno-8-56"></a> <span class="p">}</span>
<a id="__codelineno-8-57" name="__codelineno-8-57" href="#__codelineno-8-57"></a> <span class="c1">// 若无该 key ,则将键值对添加至尾部</span>
<a id="__codelineno-8-58" name="__codelineno-8-58" href="#__codelineno-8-58"></a> <span class="kd">let</span> <span class="nv">pair</span> <span class="p">=</span> <span class="n">Pair</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="n">val</span><span class="p">)</span>
<a id="__codelineno-8-59" name="__codelineno-8-59" href="#__codelineno-8-59"></a> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">].</span><span class="n">append</span><span class="p">(</span><span class="n">pair</span><span class="p">)</span>
<a id="__codelineno-8-60" name="__codelineno-8-60" href="#__codelineno-8-60"></a> <span class="n">size</span> <span class="o">+=</span> <span class="mi">1</span>
<a id="__codelineno-8-61" name="__codelineno-8-61" href="#__codelineno-8-61"></a> <span class="p">}</span>
<a id="__codelineno-8-62" name="__codelineno-8-62" href="#__codelineno-8-62"></a>
<a id="__codelineno-8-63" name="__codelineno-8-63" href="#__codelineno-8-63"></a> <span class="cm">/* 删除操作 */</span>
<a id="__codelineno-8-64" name="__codelineno-8-64" href="#__codelineno-8-64"></a> <span class="kd">func</span> <span class="nf">remove</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-8-65" name="__codelineno-8-65" href="#__codelineno-8-65"></a> <span class="kd">let</span> <span class="nv">index</span> <span class="p">=</span> <span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
<a id="__codelineno-8-66" name="__codelineno-8-66" href="#__codelineno-8-66"></a> <span class="kd">let</span> <span class="nv">bucket</span> <span class="p">=</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
<a id="__codelineno-8-67" name="__codelineno-8-67" href="#__codelineno-8-67"></a> <span class="c1">// 遍历桶,从中删除键值对</span>
<a id="__codelineno-8-68" name="__codelineno-8-68" href="#__codelineno-8-68"></a> <span class="k">for</span> <span class="p">(</span><span class="n">pairIndex</span><span class="p">,</span> <span class="n">pair</span><span class="p">)</span> <span class="k">in</span> <span class="n">bucket</span><span class="p">.</span><span class="n">enumerated</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-8-69" name="__codelineno-8-69" href="#__codelineno-8-69"></a> <span class="k">if</span> <span class="n">pair</span><span class="p">.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span> <span class="p">{</span>
<a id="__codelineno-8-70" name="__codelineno-8-70" href="#__codelineno-8-70"></a> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">].</span><span class="n">remove</span><span class="p">(</span><span class="n">at</span><span class="p">:</span> <span class="n">pairIndex</span><span class="p">)</span>
<a id="__codelineno-8-71" name="__codelineno-8-71" href="#__codelineno-8-71"></a> <span class="p">}</span>
<a id="__codelineno-8-72" name="__codelineno-8-72" href="#__codelineno-8-72"></a> <span class="p">}</span>
<a id="__codelineno-8-73" name="__codelineno-8-73" href="#__codelineno-8-73"></a> <span class="n">size</span> <span class="o">-=</span> <span class="mi">1</span>
<a id="__codelineno-8-74" name="__codelineno-8-74" href="#__codelineno-8-74"></a> <span class="p">}</span>
<a id="__codelineno-8-75" name="__codelineno-8-75" href="#__codelineno-8-75"></a>
<a id="__codelineno-8-76" name="__codelineno-8-76" href="#__codelineno-8-76"></a> <span class="cm">/* 扩容哈希表 */</span>
<a id="__codelineno-8-77" name="__codelineno-8-77" href="#__codelineno-8-77"></a> <span class="kd">func</span> <span class="nf">extend</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-8-78" name="__codelineno-8-78" href="#__codelineno-8-78"></a> <span class="c1">// 暂存原哈希表</span>
<a id="__codelineno-8-79" name="__codelineno-8-79" href="#__codelineno-8-79"></a> <span class="kd">let</span> <span class="nv">bucketsTmp</span> <span class="p">=</span> <span class="n">buckets</span>
<a id="__codelineno-8-80" name="__codelineno-8-80" href="#__codelineno-8-80"></a> <span class="c1">// 初始化扩容后的新哈希表</span>
<a id="__codelineno-8-81" name="__codelineno-8-81" href="#__codelineno-8-81"></a> <span class="n">capacity</span> <span class="o">*=</span> <span class="n">extendRatio</span>
<a id="__codelineno-8-82" name="__codelineno-8-82" href="#__codelineno-8-82"></a> <span class="n">buckets</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="p">[],</span> <span class="bp">count</span><span class="p">:</span> <span class="n">capacity</span><span class="p">)</span>
<a id="__codelineno-8-83" name="__codelineno-8-83" href="#__codelineno-8-83"></a> <span class="n">size</span> <span class="p">=</span> <span class="mi">0</span>
<a id="__codelineno-8-84" name="__codelineno-8-84" href="#__codelineno-8-84"></a> <span class="c1">// 将键值对从原哈希表搬运至新哈希表</span>
<a id="__codelineno-8-85" name="__codelineno-8-85" href="#__codelineno-8-85"></a> <span class="k">for</span> <span class="n">bucket</span> <span class="k">in</span> <span class="n">bucketsTmp</span> <span class="p">{</span>
<a id="__codelineno-8-86" name="__codelineno-8-86" href="#__codelineno-8-86"></a> <span class="k">for</span> <span class="n">pair</span> <span class="k">in</span> <span class="n">bucket</span> <span class="p">{</span>
<a id="__codelineno-8-87" name="__codelineno-8-87" href="#__codelineno-8-87"></a> <span class="n">put</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">pair</span><span class="p">.</span><span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="n">pair</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-8-88" name="__codelineno-8-88" href="#__codelineno-8-88"></a> <span class="p">}</span>
<a id="__codelineno-8-89" name="__codelineno-8-89" href="#__codelineno-8-89"></a> <span class="p">}</span>
<a id="__codelineno-8-90" name="__codelineno-8-90" href="#__codelineno-8-90"></a> <span class="p">}</span>
<a id="__codelineno-8-91" name="__codelineno-8-91" href="#__codelineno-8-91"></a>
<a id="__codelineno-8-92" name="__codelineno-8-92" href="#__codelineno-8-92"></a> <span class="cm">/* 打印哈希表 */</span>
<a id="__codelineno-8-93" name="__codelineno-8-93" href="#__codelineno-8-93"></a> <span class="kd">func</span> <span class="nf">print</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-8-94" name="__codelineno-8-94" href="#__codelineno-8-94"></a> <span class="k">for</span> <span class="n">bucket</span> <span class="k">in</span> <span class="n">buckets</span> <span class="p">{</span>
<a id="__codelineno-8-95" name="__codelineno-8-95" href="#__codelineno-8-95"></a> <span class="kd">let</span> <span class="nv">res</span> <span class="p">=</span> <span class="n">bucket</span><span class="p">.</span><span class="bp">map</span> <span class="p">{</span> <span class="s">&quot;</span><span class="si">\(</span><span class="nv">$0</span><span class="p">.</span><span class="n">key</span><span class="si">)</span><span class="s"> -&gt; </span><span class="si">\(</span><span class="nv">$0</span><span class="p">.</span><span class="n">val</span><span class="si">)</span><span class="s">&quot;</span> <span class="p">}</span>
<a id="__codelineno-8-96" name="__codelineno-8-96" href="#__codelineno-8-96"></a> <span class="n">Swift</span><span class="p">.</span><span class="bp">print</span><span class="p">(</span><span class="n">res</span><span class="p">)</span>
<a id="__codelineno-8-97" name="__codelineno-8-97" href="#__codelineno-8-97"></a> <span class="p">}</span>
<a id="__codelineno-8-98" name="__codelineno-8-98" href="#__codelineno-8-98"></a> <span class="p">}</span>
<a id="__codelineno-8-99" name="__codelineno-8-99" href="#__codelineno-8-99"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
@ -3523,7 +3637,126 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">hash_map_open_addressing.swift</span><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{</span><span class="n">HashMapOpenAddressing</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{}</span>
<div class="highlight"><span class="filename">hash_map_open_addressing.swift</span><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="cm">/* 开放寻址哈希表 */</span>
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="kd">class</span> <span class="nc">HashMapOpenAddressing</span> <span class="p">{</span>
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a> <span class="kd">var</span> <span class="nv">size</span><span class="p">:</span> <span class="nb">Int</span> <span class="c1">// 键值对数量</span>
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a> <span class="kd">var</span> <span class="nv">capacity</span><span class="p">:</span> <span class="nb">Int</span> <span class="c1">// 哈希表容量</span>
<a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a> <span class="kd">var</span> <span class="nv">loadThres</span><span class="p">:</span> <span class="nb">Double</span> <span class="c1">// 触发扩容的负载因子阈值</span>
<a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a> <span class="kd">var</span> <span class="nv">extendRatio</span><span class="p">:</span> <span class="nb">Int</span> <span class="c1">// 扩容倍数</span>
<a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a> <span class="kd">var</span> <span class="nv">buckets</span><span class="p">:</span> <span class="p">[</span><span class="n">Pair</span><span class="p">?]</span> <span class="c1">// 桶数组</span>
<a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a> <span class="kd">var</span> <span class="nv">removed</span><span class="p">:</span> <span class="n">Pair</span> <span class="c1">// 删除标记</span>
<a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a>
<a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a> <span class="cm">/* 构造方法 */</span>
<a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a> <span class="kd">init</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a> <span class="n">size</span> <span class="p">=</span> <span class="mi">0</span>
<a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a> <span class="n">capacity</span> <span class="p">=</span> <span class="mi">4</span>
<a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a> <span class="n">loadThres</span> <span class="p">=</span> <span class="mi">2</span> <span class="o">/</span> <span class="mi">3</span>
<a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a> <span class="n">extendRatio</span> <span class="p">=</span> <span class="mi">2</span>
<a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a> <span class="n">buckets</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="kc">nil</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="n">capacity</span><span class="p">)</span>
<a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a> <span class="n">removed</span> <span class="p">=</span> <span class="n">Pair</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="s">&quot;-1&quot;</span><span class="p">)</span>
<a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a> <span class="p">}</span>
<a id="__codelineno-19-19" name="__codelineno-19-19" href="#__codelineno-19-19"></a>
<a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a> <span class="cm">/* 哈希函数 */</span>
<a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></a> <span class="kd">func</span> <span class="nf">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a> <span class="n">key</span> <span class="o">%</span> <span class="n">capacity</span>
<a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a> <span class="p">}</span>
<a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a>
<a id="__codelineno-19-25" name="__codelineno-19-25" href="#__codelineno-19-25"></a> <span class="cm">/* 负载因子 */</span>
<a id="__codelineno-19-26" name="__codelineno-19-26" href="#__codelineno-19-26"></a> <span class="kd">func</span> <span class="nf">loadFactor</span><span class="p">()</span> <span class="p">-&gt;</span> <span class="nb">Double</span> <span class="p">{</span>
<a id="__codelineno-19-27" name="__codelineno-19-27" href="#__codelineno-19-27"></a> <span class="nb">Double</span><span class="p">(</span><span class="n">size</span> <span class="o">/</span> <span class="n">capacity</span><span class="p">)</span>
<a id="__codelineno-19-28" name="__codelineno-19-28" href="#__codelineno-19-28"></a> <span class="p">}</span>
<a id="__codelineno-19-29" name="__codelineno-19-29" href="#__codelineno-19-29"></a>
<a id="__codelineno-19-30" name="__codelineno-19-30" href="#__codelineno-19-30"></a> <span class="cm">/* 查询操作 */</span>
<a id="__codelineno-19-31" name="__codelineno-19-31" href="#__codelineno-19-31"></a> <span class="kd">func</span> <span class="nf">get</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">String</span><span class="p">?</span> <span class="p">{</span>
<a id="__codelineno-19-32" name="__codelineno-19-32" href="#__codelineno-19-32"></a> <span class="kd">let</span> <span class="nv">index</span> <span class="p">=</span> <span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
<a id="__codelineno-19-33" name="__codelineno-19-33" href="#__codelineno-19-33"></a> <span class="c1">// 线性探测,从 index 开始向后遍历</span>
<a id="__codelineno-19-34" name="__codelineno-19-34" href="#__codelineno-19-34"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="bp">stride</span><span class="p">(</span><span class="n">from</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="n">capacity</span><span class="p">,</span> <span class="n">by</span><span class="p">:</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-19-35" name="__codelineno-19-35" href="#__codelineno-19-35"></a> <span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-19-36" name="__codelineno-19-36" href="#__codelineno-19-36"></a> <span class="kd">let</span> <span class="nv">j</span> <span class="p">=</span> <span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="n">i</span><span class="p">)</span> <span class="o">%</span> <span class="n">capacity</span>
<a id="__codelineno-19-37" name="__codelineno-19-37" href="#__codelineno-19-37"></a> <span class="c1">// 若遇到空桶,说明无此 key ,则返回 nil</span>
<a id="__codelineno-19-38" name="__codelineno-19-38" href="#__codelineno-19-38"></a> <span class="k">if</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="p">==</span> <span class="kc">nil</span> <span class="p">{</span>
<a id="__codelineno-19-39" name="__codelineno-19-39" href="#__codelineno-19-39"></a> <span class="k">return</span> <span class="kc">nil</span>
<a id="__codelineno-19-40" name="__codelineno-19-40" href="#__codelineno-19-40"></a> <span class="p">}</span>
<a id="__codelineno-19-41" name="__codelineno-19-41" href="#__codelineno-19-41"></a> <span class="c1">// 若遇到指定 key ,则返回对应 val</span>
<a id="__codelineno-19-42" name="__codelineno-19-42" href="#__codelineno-19-42"></a> <span class="k">if</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]?.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span><span class="p">,</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="n">removed</span> <span class="p">{</span>
<a id="__codelineno-19-43" name="__codelineno-19-43" href="#__codelineno-19-43"></a> <span class="k">return</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]?.</span><span class="n">val</span>
<a id="__codelineno-19-44" name="__codelineno-19-44" href="#__codelineno-19-44"></a> <span class="p">}</span>
<a id="__codelineno-19-45" name="__codelineno-19-45" href="#__codelineno-19-45"></a> <span class="p">}</span>
<a id="__codelineno-19-46" name="__codelineno-19-46" href="#__codelineno-19-46"></a> <span class="k">return</span> <span class="kc">nil</span>
<a id="__codelineno-19-47" name="__codelineno-19-47" href="#__codelineno-19-47"></a> <span class="p">}</span>
<a id="__codelineno-19-48" name="__codelineno-19-48" href="#__codelineno-19-48"></a>
<a id="__codelineno-19-49" name="__codelineno-19-49" href="#__codelineno-19-49"></a> <span class="cm">/* 添加操作 */</span>
<a id="__codelineno-19-50" name="__codelineno-19-50" href="#__codelineno-19-50"></a> <span class="kd">func</span> <span class="nf">put</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="nb">String</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-19-51" name="__codelineno-19-51" href="#__codelineno-19-51"></a> <span class="c1">// 当负载因子超过阈值时,执行扩容</span>
<a id="__codelineno-19-52" name="__codelineno-19-52" href="#__codelineno-19-52"></a> <span class="k">if</span> <span class="n">loadFactor</span><span class="p">()</span> <span class="o">&gt;</span> <span class="n">loadThres</span> <span class="p">{</span>
<a id="__codelineno-19-53" name="__codelineno-19-53" href="#__codelineno-19-53"></a> <span class="bp">extend</span><span class="p">()</span>
<a id="__codelineno-19-54" name="__codelineno-19-54" href="#__codelineno-19-54"></a> <span class="p">}</span>
<a id="__codelineno-19-55" name="__codelineno-19-55" href="#__codelineno-19-55"></a> <span class="kd">let</span> <span class="nv">index</span> <span class="p">=</span> <span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
<a id="__codelineno-19-56" name="__codelineno-19-56" href="#__codelineno-19-56"></a> <span class="c1">// 线性探测,从 index 开始向后遍历</span>
<a id="__codelineno-19-57" name="__codelineno-19-57" href="#__codelineno-19-57"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="bp">stride</span><span class="p">(</span><span class="n">from</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">through</span><span class="p">:</span> <span class="n">capacity</span><span class="p">,</span> <span class="n">by</span><span class="p">:</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-19-58" name="__codelineno-19-58" href="#__codelineno-19-58"></a> <span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-19-59" name="__codelineno-19-59" href="#__codelineno-19-59"></a> <span class="kd">let</span> <span class="nv">j</span> <span class="p">=</span> <span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="n">i</span><span class="p">)</span> <span class="o">%</span> <span class="n">capacity</span>
<a id="__codelineno-19-60" name="__codelineno-19-60" href="#__codelineno-19-60"></a> <span class="c1">// 若遇到空桶、或带有删除标记的桶,则将键值对放入该桶</span>
<a id="__codelineno-19-61" name="__codelineno-19-61" href="#__codelineno-19-61"></a> <span class="k">if</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="p">==</span> <span class="kc">nil</span> <span class="o">||</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="p">==</span> <span class="n">removed</span> <span class="p">{</span>
<a id="__codelineno-19-62" name="__codelineno-19-62" href="#__codelineno-19-62"></a> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="p">=</span> <span class="n">Pair</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="n">val</span><span class="p">)</span>
<a id="__codelineno-19-63" name="__codelineno-19-63" href="#__codelineno-19-63"></a> <span class="n">size</span> <span class="o">+=</span> <span class="mi">1</span>
<a id="__codelineno-19-64" name="__codelineno-19-64" href="#__codelineno-19-64"></a> <span class="k">return</span>
<a id="__codelineno-19-65" name="__codelineno-19-65" href="#__codelineno-19-65"></a> <span class="p">}</span>
<a id="__codelineno-19-66" name="__codelineno-19-66" href="#__codelineno-19-66"></a> <span class="c1">// 若遇到指定 key ,则更新对应 val</span>
<a id="__codelineno-19-67" name="__codelineno-19-67" href="#__codelineno-19-67"></a> <span class="k">if</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]?.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span> <span class="p">{</span>
<a id="__codelineno-19-68" name="__codelineno-19-68" href="#__codelineno-19-68"></a> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]?.</span><span class="n">val</span> <span class="p">=</span> <span class="n">val</span>
<a id="__codelineno-19-69" name="__codelineno-19-69" href="#__codelineno-19-69"></a> <span class="k">return</span>
<a id="__codelineno-19-70" name="__codelineno-19-70" href="#__codelineno-19-70"></a> <span class="p">}</span>
<a id="__codelineno-19-71" name="__codelineno-19-71" href="#__codelineno-19-71"></a> <span class="p">}</span>
<a id="__codelineno-19-72" name="__codelineno-19-72" href="#__codelineno-19-72"></a> <span class="p">}</span>
<a id="__codelineno-19-73" name="__codelineno-19-73" href="#__codelineno-19-73"></a>
<a id="__codelineno-19-74" name="__codelineno-19-74" href="#__codelineno-19-74"></a> <span class="cm">/* 删除操作 */</span>
<a id="__codelineno-19-75" name="__codelineno-19-75" href="#__codelineno-19-75"></a> <span class="kd">func</span> <span class="nf">remove</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-19-76" name="__codelineno-19-76" href="#__codelineno-19-76"></a> <span class="kd">let</span> <span class="nv">index</span> <span class="p">=</span> <span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
<a id="__codelineno-19-77" name="__codelineno-19-77" href="#__codelineno-19-77"></a> <span class="c1">// 线性探测,从 index 开始向后遍历</span>
<a id="__codelineno-19-78" name="__codelineno-19-78" href="#__codelineno-19-78"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="bp">stride</span><span class="p">(</span><span class="n">from</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="n">capacity</span><span class="p">,</span> <span class="n">by</span><span class="p">:</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-19-79" name="__codelineno-19-79" href="#__codelineno-19-79"></a> <span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-19-80" name="__codelineno-19-80" href="#__codelineno-19-80"></a> <span class="kd">let</span> <span class="nv">j</span> <span class="p">=</span> <span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="n">i</span><span class="p">)</span> <span class="o">%</span> <span class="n">capacity</span>
<a id="__codelineno-19-81" name="__codelineno-19-81" href="#__codelineno-19-81"></a> <span class="c1">// 若遇到空桶,说明无此 key ,则直接返回</span>
<a id="__codelineno-19-82" name="__codelineno-19-82" href="#__codelineno-19-82"></a> <span class="k">if</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="p">==</span> <span class="kc">nil</span> <span class="p">{</span>
<a id="__codelineno-19-83" name="__codelineno-19-83" href="#__codelineno-19-83"></a> <span class="k">return</span>
<a id="__codelineno-19-84" name="__codelineno-19-84" href="#__codelineno-19-84"></a> <span class="p">}</span>
<a id="__codelineno-19-85" name="__codelineno-19-85" href="#__codelineno-19-85"></a> <span class="c1">// 若遇到指定 key ,则标记删除并返回</span>
<a id="__codelineno-19-86" name="__codelineno-19-86" href="#__codelineno-19-86"></a> <span class="k">if</span> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]?.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span> <span class="p">{</span>
<a id="__codelineno-19-87" name="__codelineno-19-87" href="#__codelineno-19-87"></a> <span class="n">buckets</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="p">=</span> <span class="n">removed</span>
<a id="__codelineno-19-88" name="__codelineno-19-88" href="#__codelineno-19-88"></a> <span class="n">size</span> <span class="o">-=</span> <span class="mi">1</span>
<a id="__codelineno-19-89" name="__codelineno-19-89" href="#__codelineno-19-89"></a> <span class="k">return</span>
<a id="__codelineno-19-90" name="__codelineno-19-90" href="#__codelineno-19-90"></a> <span class="p">}</span>
<a id="__codelineno-19-91" name="__codelineno-19-91" href="#__codelineno-19-91"></a> <span class="p">}</span>
<a id="__codelineno-19-92" name="__codelineno-19-92" href="#__codelineno-19-92"></a> <span class="p">}</span>
<a id="__codelineno-19-93" name="__codelineno-19-93" href="#__codelineno-19-93"></a>
<a id="__codelineno-19-94" name="__codelineno-19-94" href="#__codelineno-19-94"></a> <span class="cm">/* 扩容哈希表 */</span>
<a id="__codelineno-19-95" name="__codelineno-19-95" href="#__codelineno-19-95"></a> <span class="kd">func</span> <span class="nf">extend</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-19-96" name="__codelineno-19-96" href="#__codelineno-19-96"></a> <span class="c1">// 暂存原哈希表</span>
<a id="__codelineno-19-97" name="__codelineno-19-97" href="#__codelineno-19-97"></a> <span class="kd">let</span> <span class="nv">bucketsTmp</span> <span class="p">=</span> <span class="n">buckets</span>
<a id="__codelineno-19-98" name="__codelineno-19-98" href="#__codelineno-19-98"></a> <span class="c1">// 初始化扩容后的新哈希表</span>
<a id="__codelineno-19-99" name="__codelineno-19-99" href="#__codelineno-19-99"></a> <span class="n">capacity</span> <span class="o">*=</span> <span class="n">extendRatio</span>
<a id="__codelineno-19-100" name="__codelineno-19-100" href="#__codelineno-19-100"></a> <span class="n">buckets</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="kc">nil</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="n">capacity</span><span class="p">)</span>
<a id="__codelineno-19-101" name="__codelineno-19-101" href="#__codelineno-19-101"></a> <span class="n">size</span> <span class="p">=</span> <span class="mi">0</span>
<a id="__codelineno-19-102" name="__codelineno-19-102" href="#__codelineno-19-102"></a> <span class="c1">// 将键值对从原哈希表搬运至新哈希表</span>
<a id="__codelineno-19-103" name="__codelineno-19-103" href="#__codelineno-19-103"></a> <span class="k">for</span> <span class="n">pair</span> <span class="k">in</span> <span class="n">bucketsTmp</span> <span class="p">{</span>
<a id="__codelineno-19-104" name="__codelineno-19-104" href="#__codelineno-19-104"></a> <span class="k">if</span> <span class="kd">let</span> <span class="nv">pair</span><span class="p">,</span> <span class="n">pair</span> <span class="o">!=</span> <span class="n">removed</span> <span class="p">{</span>
<a id="__codelineno-19-105" name="__codelineno-19-105" href="#__codelineno-19-105"></a> <span class="n">put</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">pair</span><span class="p">.</span><span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="n">pair</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-19-106" name="__codelineno-19-106" href="#__codelineno-19-106"></a> <span class="p">}</span>
<a id="__codelineno-19-107" name="__codelineno-19-107" href="#__codelineno-19-107"></a> <span class="p">}</span>
<a id="__codelineno-19-108" name="__codelineno-19-108" href="#__codelineno-19-108"></a> <span class="p">}</span>
<a id="__codelineno-19-109" name="__codelineno-19-109" href="#__codelineno-19-109"></a>
<a id="__codelineno-19-110" name="__codelineno-19-110" href="#__codelineno-19-110"></a> <span class="cm">/* 打印哈希表 */</span>
<a id="__codelineno-19-111" name="__codelineno-19-111" href="#__codelineno-19-111"></a> <span class="kd">func</span> <span class="nf">print</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-19-112" name="__codelineno-19-112" href="#__codelineno-19-112"></a> <span class="k">for</span> <span class="n">pair</span> <span class="k">in</span> <span class="n">buckets</span> <span class="p">{</span>
<a id="__codelineno-19-113" name="__codelineno-19-113" href="#__codelineno-19-113"></a> <span class="k">if</span> <span class="kd">let</span> <span class="nv">pair</span> <span class="p">{</span>
<a id="__codelineno-19-114" name="__codelineno-19-114" href="#__codelineno-19-114"></a> <span class="n">Swift</span><span class="p">.</span><span class="bp">print</span><span class="p">(</span><span class="s">&quot;</span><span class="si">\(</span><span class="n">pair</span><span class="p">.</span><span class="n">key</span><span class="si">)</span><span class="s"> -&gt; </span><span class="si">\(</span><span class="n">pair</span><span class="p">.</span><span class="n">val</span><span class="si">)</span><span class="s">&quot;</span><span class="p">)</span>
<a id="__codelineno-19-115" name="__codelineno-19-115" href="#__codelineno-19-115"></a> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<a id="__codelineno-19-116" name="__codelineno-19-116" href="#__codelineno-19-116"></a> <span class="n">Swift</span><span class="p">.</span><span class="bp">print</span><span class="p">(</span><span class="s">&quot;null&quot;</span><span class="p">)</span>
<a id="__codelineno-19-117" name="__codelineno-19-117" href="#__codelineno-19-117"></a> <span class="p">}</span>
<a id="__codelineno-19-118" name="__codelineno-19-118" href="#__codelineno-19-118"></a> <span class="p">}</span>
<a id="__codelineno-19-119" name="__codelineno-19-119" href="#__codelineno-19-119"></a> <span class="p">}</span>
<a id="__codelineno-19-120" name="__codelineno-19-120" href="#__codelineno-19-120"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1989,6 +1989,8 @@
@ -2018,7 +2020,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1910,6 +1910,8 @@
@ -1939,7 +1941,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
@ -2109,7 +2125,7 @@
<h1 id="11">1.1. &nbsp; 算法无处不在<a class="headerlink" href="#11" title="Permanent link">&para;</a></h1>
<p>当我们听到“算法”这个词时,很自然地会想到数学。然而实际上,许多算法并不涉及复杂数学,而是更多地依赖于基本逻辑,这些逻辑在我们的日常生活中处处可见。</p>
<p>在正式探讨算法之前,有一个有趣的事实值得分享:<strong>实际上,你已经学会了许多算法,并习惯将他们应用到日常生活中了</strong>。下面,我将举两个具体例子来证实这一点。</p>
<p>在正式探讨算法之前,有一个有趣的事实值得分享:<strong>你已经在不知不觉中学会了许多算法,并习惯将它们应用到日常生活中了</strong>。下面,我将举即个具体例子来证实这一点。</p>
<p><strong>例一:拼装积木</strong>。一套积木,除了包含许多零件之外,还附有详细的组装说明书。我们按照说明书一步步操作,就能组装出精美的积木模型。</p>
<p>从数据结构与算法的角度来看,积木的各种形状和连接方式代表数据结构,而组装说明书上的一系列步骤则是算法。</p>
<p><img alt="拼装积木" src="../algorithms_are_everywhere.assets/assembling_blocks.jpg" /></p>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1910,6 +1910,8 @@
@ -1939,7 +1941,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1898,6 +1898,8 @@
@ -1927,7 +1929,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1969,6 +1969,8 @@
@ -1998,7 +2000,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1910,6 +1910,8 @@
@ -1939,7 +1941,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1896,6 +1896,8 @@
@ -1925,7 +1927,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
@ -2500,7 +2516,7 @@
<a id="__codelineno-13-9" name="__codelineno-13-9" href="#__codelineno-13-9"></a> <span class="n">j</span> <span class="o">=</span> <span class="n">m</span> <span class="o">-</span> <span class="mi">1</span> <span class="c1"># target 在区间 [i, m-1] 中</span>
<a id="__codelineno-13-10" name="__codelineno-13-10" href="#__codelineno-13-10"></a> <span class="k">else</span><span class="p">:</span>
<a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a> <span class="n">i</span> <span class="o">=</span> <span class="n">m</span> <span class="o">+</span> <span class="mi">1</span> <span class="c1"># 首个大于 target 的元素在区间 [m+1, j] 中</span>
<a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a> <span class="k">if</span> <span class="n">j</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">nums</span><span class="p">)</span> <span class="ow">or</span> <span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="n">target</span><span class="p">:</span>
<a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a> <span class="k">if</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="n">target</span><span class="p">:</span>
<a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span> <span class="c1"># 未找到目标元素,返回 -1</span>
<a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a> <span class="k">return</span> <span class="n">j</span>
</code></pre></div>
@ -2547,7 +2563,7 @@
<a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">m</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// 首个大于 target 的元素在区间 [m+1, j] 中</span>
<a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">j</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">nums</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">target</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">target</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-16" name="__codelineno-15-16" href="#__codelineno-15-16"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="mf">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// 未找到目标元素,返回 -1</span>
<a id="__codelineno-15-17" name="__codelineno-15-17" href="#__codelineno-15-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-18" name="__codelineno-15-18" href="#__codelineno-15-18"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">j</span><span class="p">;</span>
@ -2568,7 +2584,7 @@
<a id="__codelineno-16-11" name="__codelineno-16-11" href="#__codelineno-16-11"></a><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">m</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// 首个大于 target 的元素在区间 [m+1, j] 中</span>
<a id="__codelineno-16-12" name="__codelineno-16-12" href="#__codelineno-16-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-13" name="__codelineno-16-13" href="#__codelineno-16-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">j</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">nums</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">target</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">target</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-15" name="__codelineno-16-15" href="#__codelineno-16-15"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="mf">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// 未找到目标元素,返回 -1</span>
<a id="__codelineno-16-16" name="__codelineno-16-16" href="#__codelineno-16-16"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-17" name="__codelineno-16-17" href="#__codelineno-16-17"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">j</span><span class="p">;</span>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1910,6 +1910,8 @@
@ -1939,7 +1941,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1962,6 +1962,8 @@
@ -1991,7 +1993,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1969,6 +1969,8 @@
@ -1998,7 +2000,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1948,6 +1948,8 @@
@ -1977,7 +1979,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1975,6 +1975,8 @@
@ -2004,7 +2006,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1975,6 +1975,8 @@
@ -2004,7 +2006,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -2009,6 +2009,8 @@
@ -2038,7 +2040,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1955,6 +1955,8 @@
@ -1984,7 +1986,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -2050,6 +2050,8 @@
@ -2079,7 +2081,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1989,6 +1989,8 @@
@ -2018,7 +2020,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1996,6 +1996,8 @@
@ -2025,7 +2027,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1988,6 +1988,8 @@
@ -2017,7 +2019,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1900,6 +1900,8 @@
@ -1929,7 +1931,21 @@
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

View file

@ -1941,6 +1941,8 @@
@ -1970,7 +1972,21 @@
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
@ -2188,6 +2204,10 @@
<p class="admonition-title">在 C++ 中,函数被划分到 <code>private</code><code>public</code> 中,这方面有什么考量吗?为什么要将 <code>height()</code> 函数和 <code>updateHeight()</code> 函数分别放在 <code>public</code><code>private</code> 中呢?</p>
<p>主要看方法的使用范围,如果方法只在类内部使用,那么就设计为 <code>private</code> 。例如,用户单独调用 <code>updateHeight()</code> 是没有意义的,它只是插入、删除操作中的一步。而 <code>height()</code> 是访问结点高度,类似于 <code>vector.size()</code> ,因此设置成 <code>public</code> 以便使用。</p>
</div>
<div class="admonition question">
<p class="admonition-title">请问如何从一组输入数据构建一个二叉搜索树?根节点的选择是不是很重要?</p>
<p>是的,构建树的方法是 <code>build_tree()</code> ,已在源代码中给出。至于根节点的选择,我们通常会将输入数据排序,然后用中点元素作为根节点,再递归地构建左右子树。这样做可以最大程度保证树的平衡性。</p>
</div>

View file

@ -1891,6 +1891,8 @@
@ -1920,7 +1922,21 @@
<li class="md-nav__item">
<a href="chapter_dynamic_programming/intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="chapter_dynamic_programming/dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>

File diff suppressed because one or more lines are too long

View file

@ -2,412 +2,412 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.hello-algo.com/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_appendix/contribution/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_appendix/installation/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_array_and_linkedlist/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_array_and_linkedlist/array/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_array_and_linkedlist/linked_list/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_array_and_linkedlist/list/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_array_and_linkedlist/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_backtracking/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_backtracking/backtracking_algorithm/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_backtracking/n_queens_problem/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_backtracking/permutations_problem/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_backtracking/subset_sum_problem/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_backtracking/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_computational_complexity/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_computational_complexity/performance_evaluation/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_computational_complexity/space_complexity/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_computational_complexity/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_computational_complexity/time_complexity/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_data_structure/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_data_structure/basic_data_types/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_data_structure/character_encoding/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_data_structure/classification_of_data_structure/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_data_structure/number_encoding/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_data_structure/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_dynamic_programming/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_dynamic_programming/dynamic_programming_solution_framework/</loc>
<lastmod>2023-06-30</lastmod>
<loc>https://www.hello-algo.com/chapter_dynamic_programming/dp_problem_features/</loc>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_dynamic_programming/intro_to_dynamic_programming/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_graph/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_graph/graph/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_graph/graph_operations/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_graph/graph_traversal/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_graph/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_hashing/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_hashing/hash_algorithm/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_hashing/hash_collision/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_hashing/hash_map/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_hashing/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_heap/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_heap/build_heap/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_heap/heap/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_heap/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_heap/top_k/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_introduction/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_introduction/algorithms_are_everywhere/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_introduction/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_introduction/what_is_dsa/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_preface/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_preface/about_the_book/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_preface/suggestions/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_preface/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_reference/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_searching/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_searching/binary_search/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_searching/binary_search_edge/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_searching/replace_linear_by_hashing/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_searching/searching_algorithm_revisited/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_searching/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/bubble_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/bucket_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/counting_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/heap_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/insertion_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/merge_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/quick_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/radix_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/selection_sort/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/sorting_algorithm/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_sorting/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_stack_and_queue/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_stack_and_queue/deque/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_stack_and_queue/queue/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_stack_and_queue/stack/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_stack_and_queue/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_tree/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_tree/array_representation_of_tree/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_tree/avl_tree/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_tree/binary_search_tree/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_tree/binary_tree/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_tree/binary_tree_traversal/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://www.hello-algo.com/chapter_tree/summary/</loc>
<lastmod>2023-06-30</lastmod>
<lastmod>2023-07-01</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

Binary file not shown.