ROSALIND|Partial Sort (PS)
給定長度為 n 的整數數列,求其中前 k 小的數字並且按遞增順序呈現。
Given: A positive integer $n \le 10^5$ and an array $A[1..n]$ of integers from $-10^5$ to $10^5$, a positive integer $k \le 1000$.
Return: The $k$ smallest elements of a sorted array $A$.
(https://rosalind.info/problems/ps/)
這題為 heap sort 的變體,它只要求提供部分排序的數列。解題的關鍵在於先從數列取出前 k 個數字建立 heap。這個 heap 的組成不一定滿足題目要求,所以我們要從數列剩餘的部分,挑出能讓 heap 最大值更小的數字來替換。
也就是說,逐一比對根節點與剩餘數字。如果根節點大於某個剩餘數字,表示當前 heap 的組成仍有調整空間,因此用該數字取代根節點,再重複 Floyd’s method 的操作來恢復 heap 的特性。重複這個步驟,直到檢查完所有剩餘數字,就能得到一個由前 k 小的數字組成的 heap。
1 | def sift_down(l: list[int], i: int, n: int): |
最後對這個大小為 k 的 heap 進行 heap sort,便能遞增排序數列前 k 小的數字。
1 | def ps(l: list[int], k: int) -> list[int]: |