改進快速排序 partition:每次 partition 後得到基準索引 idx。若 idx == k-1 結束;idx > k-1 遞歸左半;否則遞歸右半。平均 O(n),最壞 O(n²)(可用隨機基準或中位數中位數優化)。缺點:修改原數組順序。
維護大小為 K 的最大堆。遍歷數組:堆未滿直接入堆;滿後若新元素 < 堆頂,替換堆頂並下沉。最終堆中即為最小 K 個。時間 O(n log K),不修改原數組,適合流式數據/大文件。
核心思想:以 i 結尾的最大子數組和 = max(arr[i], arr[i] + 以 i-1 結尾的最大和)。
若前綴和 >0 繼續累加,否則捨棄重新開始。
代碼:
int maxSubArray(int *a, int n) {
int max_sum = a[0], cur = a[0];
for (int i=1; i 0) ? cur + a[i] : a[i];
if (cur > max_sum) max_sum = cur;
}
return max_sum;
}
時間 O(n),空間 O(1)。可擴展輸出區間端點、處理全負數組(返回最大單元素)。
固定位置 begin,對 begin..end 每個字符與 begin 交換,遞歸處理 begin+1,回溯時交換恢復。去重:交換前檢查 [begin, i) 是否已有相同字符,有則跳過。
時間 O(n!),空間 O(n) 遞歸棧。
左移 k 位:
1. 逆序前 k 個
2. 逆序後 n-k 個
3. 逆序整個數組
例:1234567 左移 3 → 321 7654 → 4567123
右移 k 位:對稱操作(先逆序後 k 個)。
時間 O(n),空間 O(1),無需額外緩衝區。
| 問題 | 最優時間 | 空間 | 關鍵技巧 |
|---|---|---|---|
| TopK | O(n) 平均 / O(n log K) | O(1) / O(K) | QuickSelect / 堆 |
| 最大子數組和 | O(n) | O(1) | Kadane 動態規劃 |
| 全排列 | O(n!) | O(n) | 回溯 + 交換去重 |
| 循環移位 | O(n) | O(1) | 三次逆序 |
next_permutation 實現邏輯。