mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-12 23:36:06 +00:00
deploy
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
|
||||
<meta name="description" content="Data Structures and Algorithms Crash Course with Animated Illustrations and Off-the-Shelf Code">
|
||||
<meta name="description" content="Data structures and algorithms tutorial with animated illustrations and ready-to-run code">
|
||||
|
||||
|
||||
<meta name="author" content="krahets">
|
||||
@@ -576,7 +576,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 1. Encounter With Algorithms
|
||||
Chapter 1. Encounter with Algorithms
|
||||
|
||||
|
||||
|
||||
@@ -598,7 +598,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 1. Encounter With Algorithms
|
||||
Chapter 1. Encounter with Algorithms
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1183,7 +1183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 4. Array and Linked List
|
||||
Chapter 4. Arrays and Linked Lists
|
||||
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 4. Array and Linked List
|
||||
Chapter 4. Arrays and Linked Lists
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1311,7 +1311,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Memory and Cache *
|
||||
4.4 Random-Access Memory and Cache *
|
||||
|
||||
|
||||
|
||||
@@ -1402,7 +1402,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 5. Stack and Queue
|
||||
Chapter 5. Stacks and Queues
|
||||
|
||||
|
||||
|
||||
@@ -1424,7 +1424,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 5. Stack and Queue
|
||||
Chapter 5. Stacks and Queues
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1502,7 +1502,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
5.3 Double-Ended Queue
|
||||
5.3 Deque
|
||||
|
||||
|
||||
|
||||
@@ -1593,7 +1593,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 6. Hashing
|
||||
Chapter 6. Hash Table
|
||||
|
||||
|
||||
|
||||
@@ -1615,7 +1615,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 6. Hashing
|
||||
Chapter 6. Hash Table
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1888,7 +1888,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Array Representation of Tree
|
||||
7.3 Array Representation of Binary Trees
|
||||
|
||||
|
||||
|
||||
@@ -2107,7 +2107,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.2 Building a Heap
|
||||
8.2 Heap Construction Operation
|
||||
|
||||
|
||||
|
||||
@@ -2135,7 +2135,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Top-K Problem
|
||||
8.3 Top-k Problem
|
||||
|
||||
|
||||
|
||||
@@ -2493,7 +2493,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2521,7 +2521,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2577,7 +2577,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2726,7 +2726,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3199,7 +3199,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Hanoi Tower Problem
|
||||
12.4 Hanota Problem
|
||||
|
||||
|
||||
|
||||
@@ -4194,7 +4194,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology Table
|
||||
16.3 Glossary
|
||||
|
||||
|
||||
|
||||
@@ -4389,7 +4389,7 @@
|
||||
<p><img alt="Example data for edit distance" class="animation-figure" src="../edit_distance_problem.assets/edit_distance_example.png" /></p>
|
||||
<p align="center"> Figure 14-27 Example data for edit distance </p>
|
||||
|
||||
<p><strong>The edit distance problem can be naturally explained using the decision tree model</strong>. Strings correspond to tree nodes, and a round of decision (one edit operation) corresponds to an edge of the tree.</p>
|
||||
<p><strong>The edit distance problem can be naturally explained using the decision tree model</strong>. Strings correspond to tree nodes, and each edit operation corresponds to an edge in the tree.</p>
|
||||
<p>As shown in Figure 14-28, without restricting operations, each node can branch into many edges, with each edge corresponding to one operation, meaning there are many possible paths to transform <code>hello</code> into <code>algo</code>.</p>
|
||||
<p>From the perspective of the decision tree, the goal of this problem is to find the shortest path between node <code>hello</code> and node <code>algo</code>.</p>
|
||||
<p><img alt="Representing edit distance problem based on decision tree model" class="animation-figure" src="../edit_distance_problem.assets/edit_distance_decision_tree.png" /></p>
|
||||
@@ -4398,7 +4398,7 @@
|
||||
<h3 id="1-dynamic-programming-approach">1. Dynamic Programming Approach<a class="headerlink" href="#1-dynamic-programming-approach" title="Permanent link">¶</a></h3>
|
||||
<p><strong>Step 1: Think about the decisions in each round, define the state, and thus obtain the <span class="arithmatex">\(dp\)</span> table</strong></p>
|
||||
<p>Each round of decision involves performing one edit operation on string <span class="arithmatex">\(s\)</span>.</p>
|
||||
<p>We want the problem scale to gradually decrease during the editing process, which allows us to construct subproblems. Let the lengths of strings <span class="arithmatex">\(s\)</span> and <span class="arithmatex">\(t\)</span> be <span class="arithmatex">\(n\)</span> and <span class="arithmatex">\(m\)</span> respectively. We first consider the tail characters of the two strings, <span class="arithmatex">\(s[n-1]\)</span> and <span class="arithmatex">\(t[m-1]\)</span>.</p>
|
||||
<p>We want the problem size to gradually decrease during the editing process so that we can construct subproblems. Let the lengths of strings <span class="arithmatex">\(s\)</span> and <span class="arithmatex">\(t\)</span> be <span class="arithmatex">\(n\)</span> and <span class="arithmatex">\(m\)</span> respectively. We first consider the tail characters of the two strings, <span class="arithmatex">\(s[n-1]\)</span> and <span class="arithmatex">\(t[m-1]\)</span>.</p>
|
||||
<ul>
|
||||
<li>If <span class="arithmatex">\(s[n-1]\)</span> and <span class="arithmatex">\(t[m-1]\)</span> are the same, we can skip them and directly consider <span class="arithmatex">\(s[n-2]\)</span> and <span class="arithmatex">\(t[m-2]\)</span>.</li>
|
||||
<li>If <span class="arithmatex">\(s[n-1]\)</span> and <span class="arithmatex">\(t[m-1]\)</span> are different, we need to perform one edit on <span class="arithmatex">\(s\)</span> (insert, delete, or replace) to make the tail characters of the two strings the same, allowing us to skip them and consider a smaller-scale problem.</li>
|
||||
@@ -4416,7 +4416,7 @@
|
||||
<p><img alt="State transition for edit distance" class="animation-figure" src="../edit_distance_problem.assets/edit_distance_state_transfer.png" /></p>
|
||||
<p align="center"> Figure 14-29 State transition for edit distance </p>
|
||||
|
||||
<p>Based on the above analysis, the optimal substructure can be obtained: the minimum number of edits for <span class="arithmatex">\(dp[i, j]\)</span> equals the minimum among the minimum edit steps of <span class="arithmatex">\(dp[i, j-1]\)</span>, <span class="arithmatex">\(dp[i-1, j]\)</span>, and <span class="arithmatex">\(dp[i-1, j-1]\)</span>, plus the edit step <span class="arithmatex">\(1\)</span> for this time. The corresponding state transition equation is:</p>
|
||||
<p>Based on the above analysis, we obtain the optimal substructure: the minimum number of edits for <span class="arithmatex">\(dp[i, j]\)</span> equals the minimum of <span class="arithmatex">\(dp[i, j-1]\)</span>, <span class="arithmatex">\(dp[i-1, j]\)</span>, and <span class="arithmatex">\(dp[i-1, j-1]\)</span>, plus the current edit cost of <span class="arithmatex">\(1\)</span>. The corresponding state transition equation is:</p>
|
||||
<div class="arithmatex">\[
|
||||
dp[i, j] = \min(dp[i, j-1], dp[i-1, j], dp[i-1, j-1]) + 1
|
||||
\]</div>
|
||||
@@ -4806,7 +4806,7 @@ dp[i, j] = dp[i-1, j-1]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>As shown in Figure 14-30, the state transition process for the edit distance problem is very similar to the knapsack problem and can both be viewed as the process of filling a two-dimensional grid.</p>
|
||||
<p>As shown in Figure 14-30, the state transition process for the edit distance problem is very similar to that of the knapsack problem; both can be viewed as the process of filling a two-dimensional grid.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:15"><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" /><input id="__tabbed_2_12" name="__tabbed_2" type="radio" /><input id="__tabbed_2_13" name="__tabbed_2" type="radio" /><input id="__tabbed_2_14" name="__tabbed_2" type="radio" /><input id="__tabbed_2_15" 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><label for="__tabbed_2_11"><11></label><label for="__tabbed_2_12"><12></label><label for="__tabbed_2_13"><13></label><label for="__tabbed_2_14"><14></label><label for="__tabbed_2_15"><15></label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4859,8 +4859,8 @@ dp[i, j] = dp[i-1, j-1]
|
||||
<p align="center"> Figure 14-30 Dynamic programming process for edit distance </p>
|
||||
|
||||
<h3 id="3-space-optimization">3. Space Optimization<a class="headerlink" href="#3-space-optimization" title="Permanent link">¶</a></h3>
|
||||
<p>Since <span class="arithmatex">\(dp[i, j]\)</span> is transferred from the solutions above <span class="arithmatex">\(dp[i-1, j]\)</span>, to the left <span class="arithmatex">\(dp[i, j-1]\)</span>, and to the upper-left <span class="arithmatex">\(dp[i-1, j-1]\)</span>, forward traversal will lose the upper-left solution <span class="arithmatex">\(dp[i-1, j-1]\)</span>, and reverse traversal cannot build <span class="arithmatex">\(dp[i, j-1]\)</span> in advance, so neither traversal order is feasible.</p>
|
||||
<p>For this reason, we can use a variable <code>leftup</code> to temporarily store the upper-left solution <span class="arithmatex">\(dp[i-1, j-1]\)</span>, so we only need to consider the solutions to the left and above. This situation is the same as the unbounded knapsack problem, allowing for forward traversal. The code is as follows:</p>
|
||||
<p>Since <span class="arithmatex">\(dp[i, j]\)</span> depends on the states above <span class="arithmatex">\(dp[i-1, j]\)</span>, to the left <span class="arithmatex">\(dp[i, j-1]\)</span>, and at the upper-left <span class="arithmatex">\(dp[i-1, j-1]\)</span>, forward traversal will lose the upper-left state <span class="arithmatex">\(dp[i-1, j-1]\)</span>, while reverse traversal cannot construct <span class="arithmatex">\(dp[i, j-1]\)</span> in advance, so neither traversal order is suitable.</p>
|
||||
<p>For this reason, we can use a variable <code>leftup</code> to temporarily store the upper-left solution <span class="arithmatex">\(dp[i-1, j-1]\)</span>, so we only need to consider the solutions to the left and above. This situation is the same as in the unbounded knapsack problem, so we can use forward traversal. The code is as follows:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="3:13"><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" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><input id="__tabbed_3_13" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Python</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Java</label><label for="__tabbed_3_4">C#</label><label for="__tabbed_3_5">Go</label><label for="__tabbed_3_6">Swift</label><label for="__tabbed_3_7">JS</label><label for="__tabbed_3_8">TS</label><label for="__tabbed_3_9">Dart</label><label for="__tabbed_3_10">Rust</label><label for="__tabbed_3_11">C</label><label for="__tabbed_3_12">Kotlin</label><label for="__tabbed_3_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
|
||||
Reference in New Issue
Block a user