Return indices of the k largest scores in descending score order.
Start with the concrete trace below. It shows the state the algorithm must carry as it runs.
Problem trace
Top-K Scores: Use partial partition only to select top-k membership, then sort those candidate indices by their scores for the required descending order.
Input and goalReturn indices of the `k` largest scores in descending score order.
Validate k against score countFor scores [0.1,0.9,0.4,0.8] and k=2, the guard 1<=2<=4 passes.
input start0.100.910.420.83
guard1 <= k=2 <= len(scores)=4
Partition around the top-two boundarynp.argpartition(scores,-2)[-2:] selects indices 1 and 3 as an unordered candidate set; it does not promise their order.
0.10candidate index 10.910.42candidate index 30.83
candidates{1,3}scoresAtCandidates{0.9,0.8}
Read only the selected scoresAdvanced indexing scores[candidates] gives the two values 0.9 and 0.8; all other scores leave the ordering work.
selected index 1index 1: 0.90selected index 3index 3: 0.81
subsetSizek=2
Sort candidate positions by scoreargsort over [0.9,0.8] returns ascending positions [1,0]; reversing gives [0,1].
descending firstposition 0 -> index 1 -> 0.90descending secondposition 1 -> index 3 -> 0.81
arithmeticargsort=[1,0]; reverse=[0,1]
Index candidates in descending ordercandidates[[0,1]] returns original score indices [1,3], whose values satisfy 0.9>=0.8.
Use argpartition when k ranked elements are needed from a much larger score vector and fully sorting all n scores is unnecessary.
Keep true
After partition, every selected candidate belongs to the top-k score group although candidate order is unspecified; after subset argsort reversal, those same indices are descending by score.
Reuse it
Separate selection from ordering: first isolate the small set that can contain the answer, then pay sorting cost only on that set.
Read it this way: For scores [0.1,0.9,0.4,0.8] and k=2, the guard 1<=2<=4 passes. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.
Pattern: Partial selection, then sort only the selected values.
Simple idea:argpartition finds the top group without sorting every score. Sort the
small selected group for final order.
import numpy as npdef top_k_indices(scores: np.ndarray, k: int) -> np.ndarray: if not 1 <= k <= len(scores): raise ValueError("k must name an item in scores") candidates = np.argpartition(scores, -k)[-k:] return candidates[np.argsort(scores[candidates])[::-1]]
Cost:O(n+klogk) average time and O(k) selected space.