deploy
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
@@ -12,13 +12,13 @@
|
||||
<meta name="author" content="Krahets">
|
||||
|
||||
|
||||
<link rel="canonical" href="https://www.hello-algo.com/chapter_divide_and_conquer/build_binary_tree/">
|
||||
<link rel="canonical" href="https://www.hello-algo.com/chapter_divide_and_conquer/build_binary_tree_problem/">
|
||||
|
||||
|
||||
<link rel="prev" href="../divide_and_conquer/">
|
||||
|
||||
|
||||
<link rel="next" href="../../chapter_backtracking/">
|
||||
<link rel="next" href="../hanota_problem/">
|
||||
|
||||
<link rel="icon" href="../../assets/images/favicon.png">
|
||||
<meta name="generator" content="mkdocs-1.4.2, mkdocs-material-9.1.11">
|
||||
@@ -1773,6 +1773,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1833,6 +1835,20 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="../hanota_problem/" class="md-nav__link">
|
||||
12.3. 汉诺塔问题(New)
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</li>
|
||||
@@ -2276,7 +2292,7 @@
|
||||
|
||||
|
||||
|
||||
<a href="https://github.com/krahets/hello-algo/tree/main/docs/chapter_divide_and_conquer/build_binary_tree.md" title="编辑此页" class="md-content__button md-icon">
|
||||
<a href="https://github.com/krahets/hello-algo/tree/main/docs/chapter_divide_and_conquer/build_binary_tree_problem.md" title="编辑此页" class="md-content__button md-icon">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4v-2m10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1 2.1 2.1Z"/></svg>
|
||||
</a>
|
||||
@@ -2289,7 +2305,7 @@
|
||||
<p class="admonition-title">Question</p>
|
||||
<p>给定一个二叉树的前序遍历 <code>preorder</code> 和中序遍历 <code>inorder</code> ,请从中构建二叉树,返回二叉树的根节点。</p>
|
||||
</div>
|
||||
<p><img alt="构建二叉树的示例数据" src="../build_binary_tree.assets/build_tree_example.png" /></p>
|
||||
<p><img alt="构建二叉树的示例数据" src="../build_binary_tree_problem.assets/build_tree_example.png" /></p>
|
||||
<p align="center"> Fig. 构建二叉树的示例数据 </p>
|
||||
|
||||
<p>原问题定义为从 <code>preorder</code> 和 <code>inorder</code> 构建二叉树。我们首先从分治的角度分析这道题:</p>
|
||||
@@ -2310,7 +2326,7 @@
|
||||
<li>查找根节点在 <code>inorder</code> 中的索引,基于该索引可将 <code>inorder</code> 划分为 <code>[ 9 | 3 | 1 2 7 ]</code> ;</li>
|
||||
<li>根据 <code>inorder</code> 划分结果,可得左子树和右子树分别有 1 个和 3 个节点,从而可将 <code>preorder</code> 划分为 <code>[ 3 | 9 | 2 1 7 ]</code> ;</li>
|
||||
</ol>
|
||||
<p><img alt="在前序和中序遍历中划分子树" src="../build_binary_tree.assets/build_tree_preorder_inorder_division.png" /></p>
|
||||
<p><img alt="在前序和中序遍历中划分子树" src="../build_binary_tree_problem.assets/build_tree_preorder_inorder_division.png" /></p>
|
||||
<p align="center"> Fig. 在前序和中序遍历中划分子树 </p>
|
||||
|
||||
<p>至此,<strong>我们已经推导出根节点、左子树、右子树在 <code>preorder</code> 和 <code>inorder</code> 中的索引区间</strong>。而为了描述这些索引区间,我们需要借助几个指针变量:</p>
|
||||
@@ -2349,7 +2365,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<p>请注意,右子树根节点索引中的 <span class="arithmatex">\((m-l)\)</span> 的含义是“左子树的节点数量”,建议配合下图理解。</p>
|
||||
<p><img alt="根节点和左右子树的索引区间表示" src="../build_binary_tree.assets/build_tree_division_pointers.png" /></p>
|
||||
<p><img alt="根节点和左右子树的索引区间表示" src="../build_binary_tree_problem.assets/build_tree_division_pointers.png" /></p>
|
||||
<p align="center"> Fig. 根节点和左右子树的索引区间表示 </p>
|
||||
|
||||
<p>接下来就可以实现代码了。为了提升查询 <span class="arithmatex">\(m\)</span> 的效率,我们借助一个哈希表 <code>hmap</code> 来存储 <code>inorder</code> 列表元素到索引的映射。</p>
|
||||
@@ -2376,7 +2392,7 @@
|
||||
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> <span class="n">l</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
||||
<a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a> <span class="n">r</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
||||
<a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">TreeNode</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a><span class="w"> </span><span class="sd">"""构建二叉树 DFS"""</span>
|
||||
<a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a><span class="w"> </span><span class="sd">"""构建二叉树:分治"""</span>
|
||||
<a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a> <span class="c1"># 子树区间为空时终止</span>
|
||||
<a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a> <span class="k">if</span> <span class="n">r</span> <span class="o">-</span> <span class="n">l</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a> <span class="k">return</span> <span class="kc">None</span>
|
||||
@@ -2384,9 +2400,9 @@
|
||||
<a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a> <span class="n">root</span> <span class="o">=</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">preorder</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
|
||||
<a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a> <span class="c1"># 查询 m ,从而划分左右子树</span>
|
||||
<a id="__codelineno-2-16" name="__codelineno-2-16" href="#__codelineno-2-16"></a> <span class="n">m</span> <span class="o">=</span> <span class="n">hmap</span><span class="p">[</span><span class="n">preorder</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span>
|
||||
<a id="__codelineno-2-17" name="__codelineno-2-17" href="#__codelineno-2-17"></a> <span class="c1"># 递归构建左子树</span>
|
||||
<a id="__codelineno-2-17" name="__codelineno-2-17" href="#__codelineno-2-17"></a> <span class="c1"># 子问题:构建左子树</span>
|
||||
<a id="__codelineno-2-18" name="__codelineno-2-18" href="#__codelineno-2-18"></a> <span class="n">root</span><span class="o">.</span><span class="n">left</span> <span class="o">=</span> <span class="n">dfs</span><span class="p">(</span><span class="n">preorder</span><span class="p">,</span> <span class="n">inorder</span><span class="p">,</span> <span class="n">hmap</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">l</span><span class="p">,</span> <span class="n">m</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<a id="__codelineno-2-19" name="__codelineno-2-19" href="#__codelineno-2-19"></a> <span class="c1"># 递归构建右子树</span>
|
||||
<a id="__codelineno-2-19" name="__codelineno-2-19" href="#__codelineno-2-19"></a> <span class="c1"># 子问题:构建右子树</span>
|
||||
<a id="__codelineno-2-20" name="__codelineno-2-20" href="#__codelineno-2-20"></a> <span class="n">root</span><span class="o">.</span><span class="n">right</span> <span class="o">=</span> <span class="n">dfs</span><span class="p">(</span><span class="n">preorder</span><span class="p">,</span> <span class="n">inorder</span><span class="p">,</span> <span class="n">hmap</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">m</span> <span class="o">-</span> <span class="n">l</span><span class="p">,</span> <span class="n">m</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
|
||||
<a id="__codelineno-2-21" name="__codelineno-2-21" href="#__codelineno-2-21"></a> <span class="c1"># 返回根节点</span>
|
||||
<a id="__codelineno-2-22" name="__codelineno-2-22" href="#__codelineno-2-22"></a> <span class="k">return</span> <span class="n">root</span>
|
||||
@@ -2453,34 +2469,34 @@
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:10"><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" /><div class="tabbed-labels"><label for="__tabbed_2_1"><1></label><label for="__tabbed_2_2"><2></label><label for="__tabbed_2_3"><3></label><label for="__tabbed_2_4"><4></label><label for="__tabbed_2_5"><5></label><label for="__tabbed_2_6"><6></label><label for="__tabbed_2_7"><7></label><label for="__tabbed_2_8"><8></label><label for="__tabbed_2_9"><9></label><label for="__tabbed_2_10"><10></label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step1" src="../build_binary_tree.assets/built_tree_step1.png" /></p>
|
||||
<p><img alt="构建二叉树的递归过程" src="../build_binary_tree_problem.assets/built_tree_step1.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step2" src="../build_binary_tree.assets/built_tree_step2.png" /></p>
|
||||
<p><img alt="built_tree_step2" src="../build_binary_tree_problem.assets/built_tree_step2.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step3" src="../build_binary_tree.assets/built_tree_step3.png" /></p>
|
||||
<p><img alt="built_tree_step3" src="../build_binary_tree_problem.assets/built_tree_step3.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step4" src="../build_binary_tree.assets/built_tree_step4.png" /></p>
|
||||
<p><img alt="built_tree_step4" src="../build_binary_tree_problem.assets/built_tree_step4.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step5" src="../build_binary_tree.assets/built_tree_step5.png" /></p>
|
||||
<p><img alt="built_tree_step5" src="../build_binary_tree_problem.assets/built_tree_step5.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step6" src="../build_binary_tree.assets/built_tree_step6.png" /></p>
|
||||
<p><img alt="built_tree_step6" src="../build_binary_tree_problem.assets/built_tree_step6.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step7" src="../build_binary_tree.assets/built_tree_step7.png" /></p>
|
||||
<p><img alt="built_tree_step7" src="../build_binary_tree_problem.assets/built_tree_step7.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step8" src="../build_binary_tree.assets/built_tree_step8.png" /></p>
|
||||
<p><img alt="built_tree_step8" src="../build_binary_tree_problem.assets/built_tree_step8.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step9" src="../build_binary_tree.assets/built_tree_step9.png" /></p>
|
||||
<p><img alt="built_tree_step9" src="../build_binary_tree_problem.assets/built_tree_step9.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="built_tree_step10" src="../build_binary_tree.assets/built_tree_step10.png" /></p>
|
||||
<p><img alt="built_tree_step10" src="../build_binary_tree_problem.assets/built_tree_step10.png" /></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2579,13 +2595,13 @@
|
||||
|
||||
|
||||
|
||||
<a href="../../chapter_backtracking/" class="md-footer__link md-footer__link--next" aria-label="下一页: 13. &nbsp; 回溯" rel="next">
|
||||
<a href="../hanota_problem/" class="md-footer__link md-footer__link--next" aria-label="下一页: 12.3. &nbsp; 汉诺塔问题(New)" rel="next">
|
||||
<div class="md-footer__title">
|
||||
<span class="md-footer__direction">
|
||||
下一页
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
13. 回溯
|
||||
12.3. 汉诺塔问题(New)
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -18,7 +18,7 @@
|
||||
<link rel="prev" href="../">
|
||||
|
||||
|
||||
<link rel="next" href="../build_binary_tree/">
|
||||
<link rel="next" href="../build_binary_tree_problem/">
|
||||
|
||||
<link rel="icon" href="../../assets/images/favicon.png">
|
||||
<meta name="generator" content="mkdocs-1.4.2, mkdocs-material-9.1.11">
|
||||
@@ -1773,6 +1773,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1883,7 +1885,7 @@
|
||||
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="../build_binary_tree/" class="md-nav__link">
|
||||
<a href="../build_binary_tree_problem/" class="md-nav__link">
|
||||
12.2. 构建树问题(New)
|
||||
</a>
|
||||
</li>
|
||||
@@ -1891,6 +1893,20 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="../hanota_problem/" class="md-nav__link">
|
||||
12.3. 汉诺塔问题(New)
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</li>
|
||||
@@ -2384,7 +2400,7 @@
|
||||
|
||||
|
||||
|
||||
<h1 id="121">12.1. 分治<a class="headerlink" href="#121" title="Permanent link">¶</a></h1>
|
||||
<h1 id="121">12.1. 分治算法<a class="headerlink" href="#121" title="Permanent link">¶</a></h1>
|
||||
<p>「分治 Divide and Conquer」,全称分而治之,是一种非常重要的算法策略。分治通常基于递归实现,包括“分”和“治”两部分,主要步骤如下:</p>
|
||||
<ol>
|
||||
<li><strong>分(划分阶段)</strong>:递归地将原问题分解为两个或多个子问题,直至到达最小子问题时终止;</li>
|
||||
@@ -2552,7 +2568,7 @@ n(n - 4) & > 0
|
||||
|
||||
|
||||
|
||||
<a href="../build_binary_tree/" class="md-footer__link md-footer__link--next" aria-label="下一页: 12.2. &nbsp; 构建树问题(New)" rel="next">
|
||||
<a href="../build_binary_tree_problem/" class="md-footer__link md-footer__link--next" aria-label="下一页: 12.2. &nbsp; 构建树问题(New)" rel="next">
|
||||
<div class="md-footer__title">
|
||||
<span class="md-footer__direction">
|
||||
下一页
|
||||
|
||||
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 61 KiB |
@@ -1773,6 +1773,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1815,7 +1817,7 @@
|
||||
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="build_binary_tree/" class="md-nav__link">
|
||||
<a href="build_binary_tree_problem/" class="md-nav__link">
|
||||
12.2. 构建树问题(New)
|
||||
</a>
|
||||
</li>
|
||||
@@ -1823,6 +1825,20 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="hanota_problem/" class="md-nav__link">
|
||||
12.3. 汉诺塔问题(New)
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</li>
|
||||
|
||||