mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-23 16:47:13 +00:00
deploy
This commit is contained in:
@@ -62,17 +62,15 @@
|
||||
|
||||
|
||||
<link href="../../assets/stylesheets/glightbox.min.css" rel="stylesheet"/><style>
|
||||
html.glightbox-open { overflow: initial; height: 100%; }
|
||||
.gslide-title { margin-top: 0px; user-select: text; }
|
||||
.gslide-desc { color: #666; user-select: text; }
|
||||
.gslide-image img { background: white; }
|
||||
|
||||
.gscrollbar-fixer { padding-right: 15px; }
|
||||
.gdesc-inner { font-size: 0.75rem; }
|
||||
body[data-md-color-scheme="slate"] .gdesc-inner { background: var(--md-default-bg-color);}
|
||||
body[data-md-color-scheme="slate"] .gslide-title { color: var(--md-default-fg-color);}
|
||||
body[data-md-color-scheme="slate"] .gslide-desc { color: var(--md-default-fg-color);}
|
||||
</style> <script src="../../assets/javascripts/glightbox.min.js"></script></head>
|
||||
html.glightbox-open { overflow: initial; height: 100%; }
|
||||
.gslide-title { margin-top: 0px; user-select: text; }
|
||||
.gslide-desc { color: #666; user-select: text; }
|
||||
.gslide-image img { background: white; }
|
||||
.gscrollbar-fixer { padding-right: 15px; }
|
||||
.gdesc-inner { font-size: 0.75rem; }
|
||||
body[data-md-color-scheme="slate"] .gdesc-inner { background: var(--md-default-bg-color);}
|
||||
body[data-md-color-scheme="slate"] .gslide-title { color: var(--md-default-fg-color);}
|
||||
body[data-md-color-scheme="slate"] .gslide-desc { color: var(--md-default-fg-color);}</style> <script src="../../assets/javascripts/glightbox.min.js"></script></head>
|
||||
|
||||
|
||||
|
||||
@@ -3596,7 +3594,7 @@
|
||||
<ul>
|
||||
<li>泡沫排序透過交換相鄰元素來實現排序。透過新增一個標誌位來實現提前返回,我們可以將泡沫排序的最佳時間複雜度最佳化到 <span class="arithmatex">\(O(n)\)</span> 。</li>
|
||||
<li>插入排序每輪將未排序區間內的元素插入到已排序區間的正確位置,從而完成排序。雖然插入排序的時間複雜度為 <span class="arithmatex">\(O(n^2)\)</span> ,但由於單元操作相對較少,因此在小資料量的排序任務中非常受歡迎。</li>
|
||||
<li>快速排序基於哨兵劃分操作實現排序。在哨兵劃分中,有可能每次都選取到最差的基準數,導致時間複雜度劣化至 <span class="arithmatex">\(O(n^2)\)</span> 。引入中位數基準數或隨機基準數可以降低這種劣化的機率。尾遞迴方法可以有效地減少遞迴深度,將空間複雜度最佳化到 <span class="arithmatex">\(O(\log n)\)</span> 。</li>
|
||||
<li>快速排序基於哨兵劃分操作實現排序。在哨兵劃分中,有可能每次都選取到最差的基準數,導致時間複雜度劣化至 <span class="arithmatex">\(O(n^2)\)</span> 。引入中位數基準數或隨機基準數可以降低這種劣化的機率。透過優先遞迴較短子區間,可有效減小遞迴深度,將空間複雜度最佳化到 <span class="arithmatex">\(O(\log n)\)</span> 。</li>
|
||||
<li>合併排序包括劃分和合並兩個階段,典型地體現了分治策略。在合併排序中,排序陣列需要建立輔助陣列,空間複雜度為 <span class="arithmatex">\(O(n)\)</span> ;然而排序鏈結串列的空間複雜度可以最佳化至 <span class="arithmatex">\(O(1)\)</span> 。</li>
|
||||
<li>桶排序包含三個步驟:資料分桶、桶內排序和合並結果。它同樣體現了分治策略,適用於資料體量很大的情況。桶排序的關鍵在於對資料進行平均分配。</li>
|
||||
<li>計數排序是桶排序的一個特例,它透過統計資料出現的次數來實現排序。計數排序適用於資料量大但資料範圍有限的情況,並且要求資料能夠轉換為正整數。</li>
|
||||
@@ -3616,9 +3614,9 @@
|
||||
<p>哨兵劃分 <code>partition()</code> 的最後一步是交換 <code>nums[left]</code> 和 <code>nums[i]</code> 。完成交換後,基準數左邊的元素都 <code><=</code> 基準數,<strong>這就要求最後一步交換前 <code>nums[left] >= nums[i]</code> 必須成立</strong>。假設我們先“從左往右查詢”,那麼如果找不到比基準數更大的元素,<strong>則會在 <code>i == j</code> 時跳出迴圈,此時可能 <code>nums[j] == nums[i] > nums[left]</code></strong>。也就是說,此時最後一步交換操作會把一個比基準數更大的元素交換至陣列最左端,導致哨兵劃分失敗。</p>
|
||||
<p>舉個例子,給定陣列 <code>[0, 0, 0, 0, 1]</code> ,如果先“從左向右查詢”,哨兵劃分後陣列為 <code>[1, 0, 0, 0, 0]</code> ,這個結果是不正確的。</p>
|
||||
<p>再深入思考一下,如果我們選擇 <code>nums[right]</code> 為基準數,那麼正好反過來,必須先“從左往右查詢”。</p>
|
||||
<p><strong>Q</strong>:關於尾遞迴最佳化,為什麼選短的陣列能保證遞迴深度不超過 <span class="arithmatex">\(\log n\)</span> ?</p>
|
||||
<p>遞迴深度就是當前未返回的遞迴方法的數量。每輪哨兵劃分我們將原陣列劃分為兩個子陣列。在尾遞迴最佳化後,向下遞迴的子陣列長度最大為原陣列長度的一半。假設最差情況,一直為一半長度,那麼最終的遞迴深度就是 <span class="arithmatex">\(\log n\)</span> 。</p>
|
||||
<p>回顧原始的快速排序,我們有可能會連續地遞迴長度較大的陣列,最差情況下為 <span class="arithmatex">\(n\)</span>、<span class="arithmatex">\(n - 1\)</span>、<span class="arithmatex">\(\dots\)</span>、<span class="arithmatex">\(2\)</span>、<span class="arithmatex">\(1\)</span> ,遞迴深度為 <span class="arithmatex">\(n\)</span> 。尾遞迴最佳化可以避免這種情況出現。</p>
|
||||
<p><strong>Q</strong>:關於快速排序的遞迴深度最佳化,為什麼選短的陣列能保證遞迴深度不超過 <span class="arithmatex">\(\log n\)</span> ?</p>
|
||||
<p>遞迴深度就是當前未返回的遞迴方法的數量。每輪哨兵劃分我們將原陣列劃分為兩個子陣列。在遞迴深度最佳化後,向下遞迴的子陣列長度最大為原陣列長度的一半。假設最差情況,一直為一半長度,那麼最終的遞迴深度就是 <span class="arithmatex">\(\log n\)</span> 。</p>
|
||||
<p>回顧原始的快速排序,我們有可能會連續地遞迴長度較大的陣列,最差情況下為 <span class="arithmatex">\(n\)</span>、<span class="arithmatex">\(n - 1\)</span>、<span class="arithmatex">\(\dots\)</span>、<span class="arithmatex">\(2\)</span>、<span class="arithmatex">\(1\)</span> ,遞迴深度為 <span class="arithmatex">\(n\)</span> 。遞迴深度最佳化可以避免這種情況出現。</p>
|
||||
<p><strong>Q</strong>:當陣列中所有元素都相等時,快速排序的時間複雜度是 <span class="arithmatex">\(O(n^2)\)</span> 嗎?該如何處理這種退化情況?</p>
|
||||
<p>是的。對於這種情況,可以考慮透過哨兵劃分將陣列劃分為三個部分:小於、等於、大於基準數。僅向下遞迴小於和大於的兩部分。在該方法下,輸入元素全部相等的陣列,僅一輪哨兵劃分即可完成排序。</p>
|
||||
<p><strong>Q</strong>:桶排序的最差時間複雜度為什麼是 <span class="arithmatex">\(O(n^2)\)</span> ?</p>
|
||||
@@ -3873,5 +3871,7 @@ aria-label="頁脚"
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js"></script>
|
||||
|
||||
|
||||
<script>document$.subscribe(() => {const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": false, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "none"});})</script></body>
|
||||
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": false, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "none"});
|
||||
document$.subscribe(() => { lightbox.reload() });
|
||||
</script></body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user