mirror of
https://github.com/krahets/hello-algo.git
synced 2026-09-22 22:36:35 +08: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
|
||||
|
||||
|
||||
|
||||
@@ -2565,7 +2565,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2593,7 +2593,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2649,7 +2649,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2798,7 +2798,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3271,7 +3271,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Hanoi Tower Problem
|
||||
12.4 Hanota Problem
|
||||
|
||||
|
||||
|
||||
@@ -4183,7 +4183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology Table
|
||||
16.3 Glossary
|
||||
|
||||
|
||||
|
||||
@@ -4357,7 +4357,7 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="101-binary-search">10.1 Binary Search<a class="headerlink" href="#101-binary-search" title="Permanent link">¶</a></h1>
|
||||
<p><u>Binary search</u> is an efficient searching algorithm based on the divide-and-conquer strategy. It leverages the orderliness of data to reduce the search range by half in each round until the target element is found or the search interval becomes empty.</p>
|
||||
<p><u>Binary search</u> is an efficient search algorithm based on the divide-and-conquer strategy. It leverages the sorted order of the data to reduce the search range by half in each round until the target element is found or the search interval becomes empty.</p>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">Question</p>
|
||||
<p>Given an array <code>nums</code> of length <span class="arithmatex">\(n\)</span> with elements arranged in ascending order and no duplicates, search for and return the index of element <code>target</code> in the array. If the array does not contain the element, return <span class="arithmatex">\(-1\)</span>. An example is shown in Figure 10-1.</p>
|
||||
@@ -4376,7 +4376,7 @@
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
<p>If the array does not contain the target element, the search interval will eventually shrink to empty. In this case, return <span class="arithmatex">\(-1\)</span>.</p>
|
||||
<p>If the array does not contain the target element, the search interval will eventually become empty. In this case, return <span class="arithmatex">\(-1\)</span>.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:7"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1"><1></label><label for="__tabbed_1_2"><2></label><label for="__tabbed_1_3"><3></label><label for="__tabbed_1_4"><4></label><label for="__tabbed_1_5"><5></label><label for="__tabbed_1_6"><6></label><label for="__tabbed_1_7"><7></label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4404,7 +4404,7 @@
|
||||
</div>
|
||||
<p align="center"> Figure 10-2 Binary search process </p>
|
||||
|
||||
<p>It's worth noting that since both <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> are of <code>int</code> type, <strong><span class="arithmatex">\(i + j\)</span> may exceed the range of the <code>int</code> type</strong>. To avoid large number overflow, we typically use the formula <span class="arithmatex">\(m = \lfloor {i + (j - i) / 2} \rfloor\)</span> to calculate the midpoint.</p>
|
||||
<p>It's worth noting that since both <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> are of <code>int</code> type, <strong><span class="arithmatex">\(i + j\)</span> may exceed the range of the <code>int</code> type</strong>. To avoid integer overflow, we typically use the formula <span class="arithmatex">\(m = \lfloor {i + (j - i) / 2} \rfloor\)</span> to calculate the midpoint.</p>
|
||||
<p>The code is shown below:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:13"><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" /><div class="tabbed-labels"><label for="__tabbed_2_1">Python</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Java</label><label for="__tabbed_2_4">C#</label><label for="__tabbed_2_5">Go</label><label for="__tabbed_2_6">Swift</label><label for="__tabbed_2_7">JS</label><label for="__tabbed_2_8">TS</label><label for="__tabbed_2_9">Dart</label><label for="__tabbed_2_10">Rust</label><label for="__tabbed_2_11">C</label><label for="__tabbed_2_12">Kotlin</label><label for="__tabbed_2_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -4693,10 +4693,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p><strong>Time complexity is <span class="arithmatex">\(O(\log n)\)</span></strong>: In the binary loop, the interval is reduced by half each round, so the number of loops is <span class="arithmatex">\(\log_2 n\)</span>.</p>
|
||||
<p><strong>Time complexity is <span class="arithmatex">\(O(\log n)\)</span></strong>: In the binary search loop, the interval is reduced by half each round, so the number of iterations is <span class="arithmatex">\(\log_2 n\)</span>.</p>
|
||||
<p><strong>Space complexity is <span class="arithmatex">\(O(1)\)</span></strong>: Pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> use constant-size space.</p>
|
||||
<h2 id="1011-interval-representation-methods">10.1.1 Interval Representation Methods<a class="headerlink" href="#1011-interval-representation-methods" title="Permanent link">¶</a></h2>
|
||||
<p>In addition to the closed interval mentioned above, another common interval representation is the "left-closed right-open" interval, defined as <span class="arithmatex">\([0, n)\)</span>, meaning the left boundary includes itself while the right boundary does not. Under this representation, the interval <span class="arithmatex">\([i, j)\)</span> is empty when <span class="arithmatex">\(i = j\)</span>.</p>
|
||||
<p>In addition to the closed interval mentioned above, another common interval representation is the "left-closed right-open" interval, defined as <span class="arithmatex">\([0, n)\)</span>, meaning that the left boundary is inclusive while the right boundary is exclusive. Under this representation, the interval <span class="arithmatex">\([i, j)\)</span> is empty when <span class="arithmatex">\(i = j\)</span>.</p>
|
||||
<p>We can implement a binary search algorithm with the same functionality based on this representation:</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">
|
||||
@@ -4991,15 +4991,15 @@
|
||||
<p align="center"> Figure 10-3 Two interval definitions </p>
|
||||
|
||||
<h2 id="1012-advantages-and-limitations">10.1.2 Advantages and Limitations<a class="headerlink" href="#1012-advantages-and-limitations" title="Permanent link">¶</a></h2>
|
||||
<p>Binary search performs well in both time and space aspects.</p>
|
||||
<p>Binary search offers good performance in both time and space.</p>
|
||||
<ul>
|
||||
<li>Binary search has high time efficiency. With large data volumes, the logarithmic time complexity has significant advantages. For example, when the data size <span class="arithmatex">\(n = 2^{20}\)</span>, linear search requires <span class="arithmatex">\(2^{20} = 1048576\)</span> loop rounds, while binary search only needs <span class="arithmatex">\(\log_2 2^{20} = 20\)</span> rounds.</li>
|
||||
<li>Binary search has high time efficiency. With large data volumes, the logarithmic time complexity has significant advantages. For example, when the data size <span class="arithmatex">\(n = 2^{20}\)</span>, linear search requires <span class="arithmatex">\(2^{20} = 1048576\)</span> iterations, while binary search only needs <span class="arithmatex">\(\log_2 2^{20} = 20\)</span> iterations.</li>
|
||||
<li>Binary search requires no extra space. Compared to searching algorithms that require additional space (such as hash-based search), binary search is more space-efficient.</li>
|
||||
</ul>
|
||||
<p>However, binary search is not suitable for all situations, mainly for the following reasons:</p>
|
||||
<ul>
|
||||
<li>Binary search is only applicable to sorted data. If the input data is unsorted, sorting specifically to use binary search would be counterproductive, as sorting algorithms typically have a time complexity of <span class="arithmatex">\(O(n \log n)\)</span>, which is higher than both linear search and binary search. For scenarios with frequent element insertions, maintaining array orderliness requires inserting elements at specific positions with a time complexity of <span class="arithmatex">\(O(n)\)</span>, which is also very expensive.</li>
|
||||
<li>Binary search is only applicable to arrays. Binary search requires jump-style (non-contiguous) element access, and jump-style access has low efficiency in linked lists, making it unsuitable for linked lists or data structures based on linked list implementations.</li>
|
||||
<li>Binary search is only applicable to sorted data. If the input data is unsorted, sorting specifically to use binary search would be counterproductive, as sorting algorithms typically have a time complexity of <span class="arithmatex">\(O(n \log n)\)</span>, which is higher than both linear search and binary search. For scenarios with frequent element insertions, keeping the array sorted requires inserting elements at specific positions with a time complexity of <span class="arithmatex">\(O(n)\)</span>, which is also very expensive.</li>
|
||||
<li>Binary search is only applicable to arrays. Binary search requires non-contiguous, jump-style access to elements, and this kind of access is inefficient in linked lists, making it unsuitable for linked lists or linked-list-based data structures.</li>
|
||||
<li>For small data volumes, linear search performs better. In linear search, each round requires only 1 comparison operation; while in binary search, it requires 1 addition, 1 division, 1-3 comparison operations, and 1 addition (subtraction), totaling 4-6 unit operations. Therefore, when the data volume <span class="arithmatex">\(n\)</span> is small, linear search is actually faster than binary search.</li>
|
||||
</ul>
|
||||
|
||||
@@ -5048,7 +5048,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../binary_search_insertion/"
|
||||
class="md-footer__link md-footer__link--next"
|
||||
aria-label="Next: 10.2 Binary Search Insertion"
|
||||
aria-label="Next: 10.2 Binary Search Insertion Point"
|
||||
rel="next"
|
||||
>
|
||||
<div class="md-footer__title">
|
||||
@@ -5056,7 +5056,7 @@ aria-label="Footer"
|
||||
Next
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
@@ -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">
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
|
||||
<title>10.3 Binary Search Edge Cases - Hello Algo</title>
|
||||
<title>10.3 Binary Search Boundaries - Hello Algo</title>
|
||||
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
<div data-md-component="skip">
|
||||
|
||||
|
||||
<a href="#103-binary-search-edge-cases" class="md-skip">
|
||||
<a href="#103-binary-search-boundaries" class="md-skip">
|
||||
Skip to content
|
||||
</a>
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<div class="md-header__topic" data-md-component="header-topic">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
</span>
|
||||
</div>
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -2495,7 +2495,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2532,7 +2532,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2550,7 +2550,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2677,7 +2677,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2826,7 +2826,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3299,7 +3299,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Hanoi Tower Problem
|
||||
12.4 Hanota Problem
|
||||
|
||||
|
||||
|
||||
@@ -4211,7 +4211,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology Table
|
||||
16.3 Glossary
|
||||
|
||||
|
||||
|
||||
@@ -4412,11 +4412,11 @@
|
||||
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="103-binary-search-edge-cases">10.3 Binary Search Edge Cases<a class="headerlink" href="#103-binary-search-edge-cases" title="Permanent link">¶</a></h1>
|
||||
<h1 id="103-binary-search-boundaries">10.3 Binary Search Boundaries<a class="headerlink" href="#103-binary-search-boundaries" title="Permanent link">¶</a></h1>
|
||||
<h2 id="1031-finding-the-left-boundary">10.3.1 Finding the Left Boundary<a class="headerlink" href="#1031-finding-the-left-boundary" title="Permanent link">¶</a></h2>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">Question</p>
|
||||
<p>Given a sorted array <code>nums</code> of length <span class="arithmatex">\(n\)</span> that may contain duplicate elements, return the index of the leftmost element <code>target</code> in the array. If the array does not contain the element, return <span class="arithmatex">\(-1\)</span>.</p>
|
||||
<p>Given a sorted array <code>nums</code> of length <span class="arithmatex">\(n\)</span> that may contain duplicate elements, return the index of the leftmost occurrence of <code>target</code>. If the array does not contain <code>target</code>, return <span class="arithmatex">\(-1\)</span>.</p>
|
||||
</div>
|
||||
<p>Recall the method for finding the insertion point with binary search. After the search completes, <span class="arithmatex">\(i\)</span> points to the leftmost <code>target</code>, <strong>so finding the insertion point is essentially finding the index of the leftmost <code>target</code></strong>.</p>
|
||||
<p>Consider implementing the left boundary search using the insertion point finding function. Note that the array may not contain <code>target</code>, which could result in the following two cases:</p>
|
||||
@@ -4612,8 +4612,8 @@
|
||||
<p>So how do we find the rightmost <code>target</code>? The most direct approach is to modify the code and replace the pointer shrinking operation in the <code>nums[m] == target</code> case. The code is omitted here; interested readers can implement it themselves.</p>
|
||||
<p>Below we introduce two more clever methods.</p>
|
||||
<h3 id="1-reusing-left-boundary-search">1. Reusing Left Boundary Search<a class="headerlink" href="#1-reusing-left-boundary-search" title="Permanent link">¶</a></h3>
|
||||
<p>In fact, we can use the function for finding the leftmost element to find the rightmost element. The specific method is: <strong>Convert finding the rightmost <code>target</code> into finding the leftmost <code>target + 1</code></strong>.</p>
|
||||
<p>As shown in Figure 10-7, after the search completes, pointer <span class="arithmatex">\(i\)</span> points to the leftmost <code>target + 1</code> (if it exists), while <span class="arithmatex">\(j\)</span> points to the rightmost <code>target</code>, <strong>so we can simply return <span class="arithmatex">\(j\)</span></strong>.</p>
|
||||
<p>In fact, we can use the function for finding the leftmost <code>target</code> to find the rightmost <code>target</code>. The specific method is: <strong>convert finding the rightmost <code>target</code> into finding the leftmost <code>target + 1</code></strong>.</p>
|
||||
<p>As shown in Figure 10-7, after the search completes, the pointer <span class="arithmatex">\(i\)</span> points to the leftmost <code>target + 1</code> (if it exists), while <span class="arithmatex">\(j\)</span> points to the rightmost <code>target</code>, <strong>so we can return <span class="arithmatex">\(j\)</span></strong>.</p>
|
||||
<p><img alt="Converting right boundary search to left boundary search" class="animation-figure" src="../binary_search_edge.assets/binary_search_right_edge_by_left_edge.png" /></p>
|
||||
<p align="center"> Figure 10-7 Converting right boundary search to left boundary search </p>
|
||||
|
||||
@@ -4832,15 +4832,15 @@
|
||||
<p>We know that when the array does not contain <code>target</code>, <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> will eventually point to the first elements greater than and less than <code>target</code>, respectively.</p>
|
||||
<p>Therefore, as shown in Figure 10-8, we can construct an element that does not exist in the array to find the left and right boundaries.</p>
|
||||
<ul>
|
||||
<li>Finding the leftmost <code>target</code>: Can be converted to finding <code>target - 0.5</code> and returning pointer <span class="arithmatex">\(i\)</span>.</li>
|
||||
<li>Finding the rightmost <code>target</code>: Can be converted to finding <code>target + 0.5</code> and returning pointer <span class="arithmatex">\(j\)</span>.</li>
|
||||
<li>Finding the leftmost <code>target</code>: This can be converted to finding <code>target - 0.5</code> and returning the pointer <span class="arithmatex">\(i\)</span>.</li>
|
||||
<li>Finding the rightmost <code>target</code>: This can be converted to finding <code>target + 0.5</code> and returning the pointer <span class="arithmatex">\(j\)</span>.</li>
|
||||
</ul>
|
||||
<p><img alt="Converting boundary search to element search" class="animation-figure" src="../binary_search_edge.assets/binary_search_edge_by_element.png" /></p>
|
||||
<p align="center"> Figure 10-8 Converting boundary search to element search </p>
|
||||
|
||||
<p>The code is omitted here, but the following two points are worth noting:</p>
|
||||
<ul>
|
||||
<li>Since the given array does not contain decimals, we don't need to worry about how to handle equal cases.</li>
|
||||
<li>Since the given array does not contain decimal values, we do not need to worry about how to handle equality.</li>
|
||||
<li>Because this method introduces decimals, the variable <code>target</code> in the function needs to be changed to a floating-point type (Python does not require this change).</li>
|
||||
</ul>
|
||||
|
||||
@@ -4865,7 +4865,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../binary_search_insertion/"
|
||||
class="md-footer__link md-footer__link--prev"
|
||||
aria-label="Previous: 10.2 Binary Search Insertion"
|
||||
aria-label="Previous: 10.2 Binary Search Insertion Point"
|
||||
rel="prev"
|
||||
>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -4877,7 +4877,7 @@ aria-label="Footer"
|
||||
Previous
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -2504,7 +2504,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2522,7 +2522,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2593,7 +2593,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2649,7 +2649,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2798,7 +2798,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3271,7 +3271,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Hanoi Tower Problem
|
||||
12.4 Hanota Problem
|
||||
|
||||
|
||||
|
||||
@@ -4183,7 +4183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology Table
|
||||
16.3 Glossary
|
||||
|
||||
|
||||
|
||||
@@ -4357,11 +4357,11 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="102-binary-search-insertion-point">10.2 Binary Search Insertion Point<a class="headerlink" href="#102-binary-search-insertion-point" title="Permanent link">¶</a></h1>
|
||||
<p>Binary search can not only be used to search for target elements but also to solve many variant problems, such as searching for the insertion position of a target element.</p>
|
||||
<p>Binary search can be used not only to search for target elements, but also to solve many variant problems, such as finding the insertion position of a target element.</p>
|
||||
<h2 id="1021-case-without-duplicate-elements">10.2.1 Case Without Duplicate Elements<a class="headerlink" href="#1021-case-without-duplicate-elements" title="Permanent link">¶</a></h2>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">Question</p>
|
||||
<p>Given a sorted array <code>nums</code> of length <span class="arithmatex">\(n\)</span> and an element <code>target</code>, where the array contains no duplicate elements. Insert <code>target</code> into the array <code>nums</code> while maintaining its sorted order. If the array already contains the element <code>target</code>, insert it to its left. Return the index of <code>target</code> in the array after insertion. An example is shown in Figure 10-4.</p>
|
||||
<p>Given a sorted array <code>nums</code> of length <span class="arithmatex">\(n\)</span> and an element <code>target</code>, where the array contains no duplicate elements, insert <code>target</code> into <code>nums</code> while maintaining its sorted order. If <code>target</code> already exists in the array, insert it to its left. Return the index of <code>target</code> after insertion. An example is shown below.</p>
|
||||
</div>
|
||||
<p><img alt="Binary search insertion point example data" class="animation-figure" src="../binary_search_insertion.assets/binary_search_insertion_example.png" /></p>
|
||||
<p align="center"> Figure 10-4 Binary search insertion point example data </p>
|
||||
@@ -4370,8 +4370,8 @@
|
||||
<p><strong>Question 1</strong>: When the array contains <code>target</code>, is the insertion point index the same as that element's index?</p>
|
||||
<p>The problem requires inserting <code>target</code> to the left of equal elements, which means the newly inserted <code>target</code> replaces the position of the original <code>target</code>. In other words, <strong>when the array contains <code>target</code>, the insertion point index is the index of that <code>target</code></strong>.</p>
|
||||
<p><strong>Question 2</strong>: When the array does not contain <code>target</code>, what is the insertion point index?</p>
|
||||
<p>Further consider the binary search process: When <code>nums[m] < target</code>, <span class="arithmatex">\(i\)</span> moves, which means pointer <span class="arithmatex">\(i\)</span> is approaching elements greater than or equal to <code>target</code>. Similarly, pointer <span class="arithmatex">\(j\)</span> is always approaching elements less than or equal to <code>target</code>.</p>
|
||||
<p>Therefore, when the binary search ends, we must have: <span class="arithmatex">\(i\)</span> points to the first element greater than <code>target</code>, and <span class="arithmatex">\(j\)</span> points to the first element less than <code>target</code>. <strong>It's easy to see that when the array does not contain <code>target</code>, the insertion index is <span class="arithmatex">\(i\)</span></strong>. The code is shown below:</p>
|
||||
<p>To analyze this further, consider the binary search process: when <code>nums[m] < target</code>, <span class="arithmatex">\(i\)</span> moves, meaning that pointer <span class="arithmatex">\(i\)</span> is approaching elements greater than or equal to <code>target</code>. Similarly, pointer <span class="arithmatex">\(j\)</span> is always approaching elements less than or equal to <code>target</code>.</p>
|
||||
<p>Therefore, when the binary search ends, <span class="arithmatex">\(i\)</span> must point to the first element greater than <code>target</code>, and <span class="arithmatex">\(j\)</span> must point to the first element less than <code>target</code>. <strong>It follows that when the array does not contain <code>target</code>, the insertion index is <span class="arithmatex">\(i\)</span></strong>. The code is shown below:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:13"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><input id="__tabbed_1_13" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Kotlin</label><label for="__tabbed_1_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4643,7 +4643,7 @@
|
||||
<p>Based on the previous problem, assume the array may contain duplicate elements, with everything else remaining the same.</p>
|
||||
</div>
|
||||
<p>Suppose there are multiple <code>target</code> elements in the array. Ordinary binary search can only return the index of one <code>target</code>, <strong>and cannot determine how many <code>target</code> elements are to the left and right of that element</strong>.</p>
|
||||
<p>The problem requires inserting the target element at the leftmost position, <strong>so we need to find the index of the leftmost <code>target</code> in the array</strong>. Initially, consider implementing this through the steps shown in Figure 10-5:</p>
|
||||
<p>The problem requires inserting the target element at the leftmost position, <strong>so we need to find the index of the leftmost <code>target</code> in the array</strong>. A straightforward initial approach is to follow the steps shown in Figure 10-5:</p>
|
||||
<ol>
|
||||
<li>Perform binary search to obtain the index of any <code>target</code>, denoted as <span class="arithmatex">\(k\)</span>.</li>
|
||||
<li>Starting from index <span class="arithmatex">\(k\)</span>, perform linear traversal to the left, and return when the leftmost <code>target</code> is found.</li>
|
||||
@@ -4652,10 +4652,10 @@
|
||||
<p align="center"> Figure 10-5 Linear search for insertion point of duplicate elements </p>
|
||||
|
||||
<p>Although this method works, it includes linear search, resulting in a time complexity of <span class="arithmatex">\(O(n)\)</span>. When the array contains many duplicate <code>target</code> elements, this method is very inefficient.</p>
|
||||
<p>Now consider extending the binary search code. As shown in Figure 10-6, the overall process remains unchanged: calculate the midpoint index <span class="arithmatex">\(m\)</span> in each round, then compare <code>target</code> with <code>nums[m]</code>, divided into the following cases:</p>
|
||||
<p>Now consider extending the binary search code. As shown in Figure 10-6, the overall process remains unchanged: in each iteration, we first compute the midpoint index <span class="arithmatex">\(m\)</span>, then compare <code>target</code> with <code>nums[m]</code>, leading to the following cases:</p>
|
||||
<ul>
|
||||
<li>When <code>nums[m] < target</code> or <code>nums[m] > target</code>, it means <code>target</code> has not been found yet, so use the ordinary binary search interval narrowing operation to <strong>make pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> approach <code>target</code></strong>.</li>
|
||||
<li>When <code>nums[m] == target</code>, it means elements less than <code>target</code> are in the interval <span class="arithmatex">\([i, m - 1]\)</span>, so use <span class="arithmatex">\(j = m - 1\)</span> to narrow the interval, thereby <strong>making pointer <span class="arithmatex">\(j\)</span> approach elements less than <code>target</code></strong>.</li>
|
||||
<li>When <code>nums[m] < target</code> or <code>nums[m] > target</code>, it means <code>target</code> has not been found yet, so use the standard interval-shrinking operation of binary search to <strong>move pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> closer to <code>target</code></strong>.</li>
|
||||
<li>When <code>nums[m] == target</code>, it means elements less than <code>target</code> are in the interval <span class="arithmatex">\([i, m - 1]\)</span>, so use <span class="arithmatex">\(j = m - 1\)</span> to shrink the interval, thereby <strong>moving pointer <span class="arithmatex">\(j\)</span> closer to elements less than <code>target</code></strong>.</li>
|
||||
</ul>
|
||||
<p>After the loop completes, <span class="arithmatex">\(i\)</span> points to the leftmost <code>target</code>, and <span class="arithmatex">\(j\)</span> points to the first element less than <code>target</code>, <strong>so index <span class="arithmatex">\(i\)</span> is the insertion point</strong>.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:8"><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" /><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></div>
|
||||
@@ -4688,7 +4688,7 @@
|
||||
</div>
|
||||
<p align="center"> Figure 10-6 Steps for binary search insertion point of duplicate elements </p>
|
||||
|
||||
<p>Observe the following code: the operations for branches <code>nums[m] > target</code> and <code>nums[m] == target</code> are the same, so the two can be merged.</p>
|
||||
<p>Observe the following code: the branches <code>nums[m] > target</code> and <code>nums[m] == target</code> perform the same operation, so they can be merged.</p>
|
||||
<p>Even so, we can still keep the conditional branches expanded, as the logic is clearer and more readable.</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">
|
||||
@@ -4954,10 +4954,10 @@
|
||||
</div>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Tip</p>
|
||||
<p>The code in this section all uses the "closed interval" approach. Interested readers can implement the "left-closed right-open" approach themselves.</p>
|
||||
<p>The code in this section uses the "closed interval" approach throughout. Interested readers can implement the "left-closed, right-open" approach themselves.</p>
|
||||
</div>
|
||||
<p>Overall, binary search is simply about setting search targets for pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> separately. The target could be a specific element (such as <code>target</code>) or a range of elements (such as elements less than <code>target</code>).</p>
|
||||
<p>Through continuous binary iterations, both pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> gradually approach their preset targets. Ultimately, they either successfully find the answer or stop after crossing the boundaries.</p>
|
||||
<p>Overall, binary search is simply a matter of setting separate search targets for pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span>. The target may be a specific element (such as <code>target</code>) or a range of elements (such as elements less than <code>target</code>).</p>
|
||||
<p>With each iteration of binary search, pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> gradually approach their preset targets. Ultimately, they either find the answer or stop after crossing the boundary.</p>
|
||||
|
||||
<!-- Source file information -->
|
||||
|
||||
@@ -5004,7 +5004,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../binary_search_edge/"
|
||||
class="md-footer__link md-footer__link--next"
|
||||
aria-label="Next: 10.3 Binary Search Edge Cases"
|
||||
aria-label="Next: 10.3 Binary Search Boundaries"
|
||||
rel="next"
|
||||
>
|
||||
<div class="md-footer__title">
|
||||
@@ -5012,7 +5012,7 @@ aria-label="Footer"
|
||||
Next
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -2495,7 +2495,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2523,7 +2523,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2579,7 +2579,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2728,7 +2728,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3201,7 +3201,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Hanoi Tower Problem
|
||||
12.4 Hanota Problem
|
||||
|
||||
|
||||
|
||||
@@ -4113,7 +4113,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology Table
|
||||
16.3 Glossary
|
||||
|
||||
|
||||
|
||||
@@ -4285,10 +4285,10 @@
|
||||
<h2 id="chapter-contents">Chapter contents<a class="headerlink" href="#chapter-contents" title="Permanent link">¶</a></h2>
|
||||
<ul>
|
||||
<li><a href="binary_search/">10.1 Binary Search</a></li>
|
||||
<li><a href="binary_search_insertion/">10.2 Binary Search Insertion</a></li>
|
||||
<li><a href="binary_search_edge/">10.3 Binary Search Edge Cases</a></li>
|
||||
<li><a href="binary_search_insertion/">10.2 Binary Search Insertion Point</a></li>
|
||||
<li><a href="binary_search_edge/">10.3 Binary Search Boundaries</a></li>
|
||||
<li><a href="replace_linear_by_hashing/">10.4 Hash Optimization Strategy</a></li>
|
||||
<li><a href="searching_algorithm_revisited/">10.5 Search Algorithms Revisited</a></li>
|
||||
<li><a href="searching_algorithm_revisited/">10.5 Searching Algorithms Revisited</a></li>
|
||||
<li><a href="summary/">10.6 Summary</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -2495,7 +2495,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2523,7 +2523,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2649,7 +2649,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2798,7 +2798,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3271,7 +3271,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Hanoi Tower Problem
|
||||
12.4 Hanota Problem
|
||||
|
||||
|
||||
|
||||
@@ -4183,7 +4183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology Table
|
||||
16.3 Glossary
|
||||
|
||||
|
||||
|
||||
@@ -4360,10 +4360,10 @@
|
||||
<p>In algorithm problems, <strong>we often reduce the time complexity of algorithms by replacing linear search with hash-based search</strong>. Let's use an algorithm problem to deepen our understanding.</p>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">Question</p>
|
||||
<p>Given an integer array <code>nums</code> and a target element <code>target</code>, search for two elements in the array whose "sum" equals <code>target</code>, and return their array indices. Any solution will do.</p>
|
||||
<p>Given an integer array <code>nums</code> and a target value <code>target</code>, find two elements in the array whose sum is <code>target</code>, and return their indices. Any solution will do.</p>
|
||||
</div>
|
||||
<h2 id="1041-linear-search-trading-time-for-space">10.4.1 Linear Search: Trading Time for Space<a class="headerlink" href="#1041-linear-search-trading-time-for-space" title="Permanent link">¶</a></h2>
|
||||
<p>Consider directly traversing all possible combinations. As shown in Figure 10-9, we open a two-layer loop and judge in each round whether the sum of two integers equals <code>target</code>. If so, return their indices.</p>
|
||||
<p>Consider directly traversing all possible combinations. As shown in Figure 10-9, we use nested loops and check in each iteration whether the sum of two integers is <code>target</code>. If so, return their indices.</p>
|
||||
<p><img alt="Linear search solution for two sum" class="animation-figure" src="../replace_linear_by_hashing.assets/two_sum_brute_force.png" /></p>
|
||||
<p align="center"> Figure 10-9 Linear search solution for two sum </p>
|
||||
|
||||
@@ -4567,9 +4567,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>This method has a time complexity of <span class="arithmatex">\(O(n^2)\)</span> and a space complexity of <span class="arithmatex">\(O(1)\)</span>, which is very time-consuming with large data volumes.</p>
|
||||
<p>This method has a time complexity of <span class="arithmatex">\(O(n^2)\)</span> and a space complexity of <span class="arithmatex">\(O(1)\)</span>, making it very time-consuming on large inputs.</p>
|
||||
<h2 id="1042-hash-based-search-trading-space-for-time">10.4.2 Hash-Based Search: Trading Space for Time<a class="headerlink" href="#1042-hash-based-search-trading-space-for-time" title="Permanent link">¶</a></h2>
|
||||
<p>Consider using a hash table where key-value pairs are array elements and element indices respectively. Loop through the array, performing the steps shown in Figure 10-10 in each round:</p>
|
||||
<p>Consider using a hash table whose keys are array elements and whose values are their indices. Traverse the array and perform the steps shown in Figure 10-10 in each iteration:</p>
|
||||
<ol>
|
||||
<li>Check if the number <code>target - nums[i]</code> is in the hash table. If so, directly return the indices of these two elements.</li>
|
||||
<li>Add the key-value pair <code>nums[i]</code> and index <code>i</code> to the hash table.</li>
|
||||
@@ -4589,7 +4589,7 @@
|
||||
</div>
|
||||
<p align="center"> Figure 10-10 Hash table solution for two sum </p>
|
||||
|
||||
<p>The implementation code is shown below, requiring only a single loop:</p>
|
||||
<p>The implementation is shown below and requires only a single loop:</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">
|
||||
@@ -4837,7 +4837,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<p>This method reduces the time complexity from <span class="arithmatex">\(O(n^2)\)</span> to <span class="arithmatex">\(O(n)\)</span> through hash-based search, greatly improving runtime efficiency.</p>
|
||||
<p>Since an additional hash table needs to be maintained, the space complexity is <span class="arithmatex">\(O(n)\)</span>. <strong>Nevertheless, this method achieves a more balanced overall time-space efficiency, making it the optimal solution for this problem</strong>.</p>
|
||||
<p>Since an additional hash table needs to be maintained, the space complexity is <span class="arithmatex">\(O(n)\)</span>. <strong>Nevertheless, this method offers a more balanced overall time-space trade-off, making it the optimal solution to this problem</strong>.</p>
|
||||
|
||||
<!-- Source file information -->
|
||||
|
||||
@@ -4860,7 +4860,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../binary_search_edge/"
|
||||
class="md-footer__link md-footer__link--prev"
|
||||
aria-label="Previous: 10.3 Binary Search Edge Cases"
|
||||
aria-label="Previous: 10.3 Binary Search Boundaries"
|
||||
rel="prev"
|
||||
>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -4872,7 +4872,7 @@ aria-label="Footer"
|
||||
Previous
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@@ -4884,7 +4884,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../searching_algorithm_revisited/"
|
||||
class="md-footer__link md-footer__link--next"
|
||||
aria-label="Next: 10.5 Search Algorithms Revisited"
|
||||
aria-label="Next: 10.5 Searching Algorithms Revisited"
|
||||
rel="next"
|
||||
>
|
||||
<div class="md-footer__title">
|
||||
@@ -4892,7 +4892,7 @@ aria-label="Footer"
|
||||
Next
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -2495,7 +2495,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2523,7 +2523,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2588,7 +2588,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2606,7 +2606,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2809,7 +2809,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3282,7 +3282,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
|
||||
|
||||
|
||||
|
||||
@@ -4383,9 +4383,9 @@
|
||||
<p>Searching algorithms can be divided into the following two categories based on their implementation approach:</p>
|
||||
<ul>
|
||||
<li><strong>Locating target elements by traversing the data structure</strong>, such as traversing arrays, linked lists, trees, and graphs.</li>
|
||||
<li><strong>Achieving efficient element search by utilizing data organization structure or prior information contained in the data</strong>, such as binary search, hash-based search, and binary search tree search.</li>
|
||||
<li><strong>Achieving efficient element lookup by leveraging the way data is organized or prior information about the data</strong>, such as binary search, hash-based search, and binary search tree search.</li>
|
||||
</ul>
|
||||
<p>It's not hard to see that these topics have all been covered in previous chapters, so searching algorithms are not unfamiliar to us. In this section, we will approach from a more systematic perspective and re-examine searching algorithms.</p>
|
||||
<p>As these topics have already been introduced in earlier chapters, searching algorithms should already be familiar to us. In this section, we revisit them from a more systematic perspective.</p>
|
||||
<h2 id="1051-brute-force-search">10.5.1 Brute-Force Search<a class="headerlink" href="#1051-brute-force-search" title="Permanent link">¶</a></h2>
|
||||
<p>Brute-force search locates target elements by traversing each element of the data structure.</p>
|
||||
<ul>
|
||||
@@ -4395,11 +4395,11 @@
|
||||
<p>The advantage of brute-force search is that it is simple and has good generality, <strong>requiring no data preprocessing or additional data structures</strong>.</p>
|
||||
<p>However, <strong>the time complexity of such algorithms is <span class="arithmatex">\(O(n)\)</span></strong>, where <span class="arithmatex">\(n\)</span> is the number of elements, so performance is poor when dealing with large amounts of data.</p>
|
||||
<h2 id="1052-adaptive-search">10.5.2 Adaptive Search<a class="headerlink" href="#1052-adaptive-search" title="Permanent link">¶</a></h2>
|
||||
<p>Adaptive search utilizes the unique properties of data (such as orderliness) to optimize the search process, thereby locating target elements more efficiently.</p>
|
||||
<p>Adaptive search leverages properties of the data itself (such as sorted order) to optimize the search process and locate target elements more efficiently.</p>
|
||||
<ul>
|
||||
<li>"Binary search" uses the orderliness of data to achieve efficient searching, applicable only to arrays.</li>
|
||||
<li>"Hash-based search" uses hash tables to establish key-value pair mappings between search data and target data, thereby achieving query operations.</li>
|
||||
<li>"Tree search" in specific tree structures (such as binary search trees), quickly eliminates nodes based on comparing node values to locate target elements.</li>
|
||||
<li>"Hash-based search" uses hash tables to store searchable data as key-value pairs, thereby enabling efficient queries.</li>
|
||||
<li>"Tree search" operates on specific tree structures (such as binary search trees), quickly ruling out nodes by comparing node values to locate the target element.</li>
|
||||
</ul>
|
||||
<p>The advantage of such algorithms is high efficiency, <strong>with time complexity reaching <span class="arithmatex">\(O(\log n)\)</span> or even <span class="arithmatex">\(O(1)\)</span></strong>.</p>
|
||||
<p>However, <strong>using these algorithms often requires data preprocessing</strong>. For example, binary search requires pre-sorting the array, while hash-based search and tree search both require additional data structures, and maintaining these data structures also requires extra time and space overhead.</p>
|
||||
@@ -4412,7 +4412,7 @@
|
||||
<p><img alt="Multiple search strategies" class="animation-figure" src="../searching_algorithm_revisited.assets/searching_algorithms.png" /></p>
|
||||
<p align="center"> Figure 10-11 Multiple search strategies </p>
|
||||
|
||||
<p>The operational efficiency and characteristics of the above methods are as follows:</p>
|
||||
<p>The efficiency and characteristics of these methods are summarized in Table 10-1.</p>
|
||||
<p align="center"> Table 10-1 Comparison of search algorithm efficiency </p>
|
||||
|
||||
<div class="center-table">
|
||||
@@ -4475,29 +4475,29 @@
|
||||
<p>The choice of search algorithm also depends on data volume, search performance requirements, data query and update frequency, etc.</p>
|
||||
<p><strong>Linear search</strong></p>
|
||||
<ul>
|
||||
<li>Good generality, requiring no data preprocessing operations. If we only need to query the data once, the data preprocessing time for the other three methods would be longer than linear search.</li>
|
||||
<li>Good generality, requiring no data preprocessing operations. If we need to query the data only once, the preprocessing required by the other three methods can take longer than the linear search itself.</li>
|
||||
<li>Suitable for small data volumes, where time complexity has less impact on efficiency.</li>
|
||||
<li>Suitable for scenarios with high data update frequency, as this method does not require any additional data maintenance.</li>
|
||||
</ul>
|
||||
<p><strong>Binary search</strong></p>
|
||||
<ul>
|
||||
<li>Suitable for large data volumes with stable efficiency performance, worst-case time complexity of <span class="arithmatex">\(O(\log n)\)</span>.</li>
|
||||
<li>Suitable for large datasets, with stable performance and a worst-case time complexity of <span class="arithmatex">\(O(\log n)\)</span>.</li>
|
||||
<li>Data volume cannot be too large, as storing arrays requires contiguous memory space.</li>
|
||||
<li>Not suitable for scenarios with frequent data insertion and deletion, as maintaining a sorted array has high overhead.</li>
|
||||
</ul>
|
||||
<p><strong>Hash-based search</strong></p>
|
||||
<ul>
|
||||
<li>Suitable for scenarios with high query performance requirements, with an average time complexity of <span class="arithmatex">\(O(1)\)</span>.</li>
|
||||
<li>Not suitable for scenarios requiring ordered data or range searches, as hash tables cannot maintain data orderliness.</li>
|
||||
<li>Not suitable for scenarios requiring ordered data or range searches, as hash tables cannot maintain the data in sorted order.</li>
|
||||
<li>High dependence on hash functions and hash collision handling strategies, with significant risk of performance degradation.</li>
|
||||
<li>Not suitable for excessively large data volumes, as hash tables require extra space to minimize collisions and thus provide good query performance.</li>
|
||||
</ul>
|
||||
<p><strong>Tree search</strong></p>
|
||||
<ul>
|
||||
<li>Suitable for massive data, as tree nodes are stored dispersedly in memory.</li>
|
||||
<li>Suitable for scenarios requiring maintained ordered data or range searches.</li>
|
||||
<li>Suitable for massive datasets, as tree nodes are stored non-contiguously in memory.</li>
|
||||
<li>Suitable for scenarios that require maintaining ordered data or performing range searches.</li>
|
||||
<li>During continuous node insertion and deletion, binary search trees may become skewed, degrading time complexity to <span class="arithmatex">\(O(n)\)</span>.</li>
|
||||
<li>If using AVL trees or red-black trees, all operations can run stably at <span class="arithmatex">\(O(\log n)\)</span> efficiency, but operations to maintain tree balance add extra overhead.</li>
|
||||
<li>If AVL trees or red-black trees are used, all operations can consistently run in <span class="arithmatex">\(O(\log n)\)</span> time, though maintaining tree balance adds extra overhead.</li>
|
||||
</ul>
|
||||
|
||||
<!-- Source file information -->
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -2495,7 +2495,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary Search Insertion
|
||||
10.2 Binary Search Insertion Point
|
||||
|
||||
|
||||
|
||||
@@ -2523,7 +2523,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary Search Edge Cases
|
||||
10.3 Binary Search Boundaries
|
||||
|
||||
|
||||
|
||||
@@ -2579,7 +2579,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2787,7 +2787,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting Algorithms
|
||||
11.1 Sorting Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3260,7 +3260,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Hanoi Tower Problem
|
||||
12.4 Hanota Problem
|
||||
|
||||
|
||||
|
||||
@@ -4172,7 +4172,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology Table
|
||||
16.3 Glossary
|
||||
|
||||
|
||||
|
||||
@@ -4337,11 +4337,11 @@
|
||||
<h1 id="106-summary">10.6 Summary<a class="headerlink" href="#106-summary" title="Permanent link">¶</a></h1>
|
||||
<h3 id="1-key-review">1. Key Review<a class="headerlink" href="#1-key-review" title="Permanent link">¶</a></h3>
|
||||
<ul>
|
||||
<li>Binary search relies on data orderliness and progressively reduces the search interval by half through loops. It requires input data to be sorted and is only applicable to arrays or data structures based on array implementations.</li>
|
||||
<li>Brute-force search locates data by traversing the data structure. Linear search is applicable to arrays and linked lists, while breadth-first search and depth-first search are applicable to graphs and trees. Such algorithms have good generality and require no data preprocessing, but have a relatively high time complexity of <span class="arithmatex">\(O(n)\)</span>.</li>
|
||||
<li>Binary search relies on ordered data and searches by repeatedly halving the search interval. It requires the input data to be sorted and applies only to arrays or array-based data structures.</li>
|
||||
<li>Brute-force search locates data by traversing the data structure. Linear search applies to arrays and linked lists, while breadth-first search and depth-first search apply to graphs and trees. These algorithms are broadly applicable and require no data preprocessing, but their relatively high time complexity is <span class="arithmatex">\(O(n)\)</span>.</li>
|
||||
<li>Hash-based search, tree search, and binary search are efficient search methods that can quickly locate target elements in specific data structures. Such algorithms are highly efficient with time complexity reaching <span class="arithmatex">\(O(\log n)\)</span> or even <span class="arithmatex">\(O(1)\)</span>, but typically require additional data structures.</li>
|
||||
<li>In practice, we need to analyze factors such as data scale, search performance requirements, and data query and update frequency to choose the appropriate search method.</li>
|
||||
<li>Linear search is suitable for small-scale or frequently updated data; binary search is suitable for large-scale, sorted data; hash-based search is suitable for data with high query efficiency requirements and no need for range queries; tree search is suitable for large-scale dynamic data that needs to maintain order and support range queries.</li>
|
||||
<li>Linear search is suitable for small datasets or data that is updated frequently; binary search is suitable for large sorted datasets; hash-based search is suitable when high query efficiency is required and range queries are unnecessary; tree search is suitable for large dynamic datasets that must maintain order and support range queries.</li>
|
||||
<li>Replacing linear search with hash-based search is a commonly used strategy to optimize runtime, reducing time complexity from <span class="arithmatex">\(O(n)\)</span> to <span class="arithmatex">\(O(1)\)</span>.</li>
|
||||
</ul>
|
||||
|
||||
@@ -4366,7 +4366,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../searching_algorithm_revisited/"
|
||||
class="md-footer__link md-footer__link--prev"
|
||||
aria-label="Previous: 10.5 Search Algorithms Revisited"
|
||||
aria-label="Previous: 10.5 Searching Algorithms Revisited"
|
||||
rel="prev"
|
||||
>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -4378,7 +4378,7 @@ aria-label="Footer"
|
||||
Previous
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
10.5 Search Algorithms Revisited
|
||||
10.5 Searching Algorithms Revisited
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user