PrepStack · Markdown HTML

Quickselect 第 K 顺序统计

分治与归并计数 · HTML

数学 / 逻辑形态

目标为升序零基 target。partition(lo,hi) 后 pivot 位于 p,左侧 <= pivot、右侧 > pivot。p=target 返回;否则永久排除不含 target 的一侧。

识别信号

容易误判的相似信号

SignalWhy it is different
在线数据流未来项会改变排名,应用有界堆或双堆。
严格最坏界普通 Quickselect 最坏 O(n²);需要堆或确定性 pivot。
需要稳定全序partition 改写顺序且不稳定;完整排序更合适。

核心不变量

目标秩始终在当前闭区间 [lo,hi];每次 partition 后 pivot 的秩位置已确定,不含 target 的一侧可永久丢弃。

状态、转移与处理顺序

ItemDefinition
State可变数组、lo/hi、零基 target 和随机 pivot。
Transitionpartition 得 p;p<target 则 lo=p+1,p>target 则 hi=p-1,否则返回。
Frontier / order唯一仍可能包含目标秩的连续区间;与 Quicksort 不同,不处理另一侧。

Python 骨架

from random import randrange

def kth_smallest(nums, k):
    if not 1 <= k <= len(nums): raise ValueError('k')
    a, target = list(nums), k - 1
    lo, hi = 0, len(a) - 1
    while lo <= hi:
        q = randrange(lo, hi + 1)
        a[q], a[hi] = a[hi], a[q]
        pivot, p = a[hi], lo
        for i in range(lo, hi):
            if a[i] <= pivot:
                a[p], a[i] = a[i], a[p]; p += 1
        a[p], a[hi] = a[hi], a[p]
        if p == target: return a[p]
        if p < target: lo = p + 1
        else: hi = p - 1

正确性思路

  1. partition 后 p 左侧均 <= pivot、右侧均 > pivot,pivot 的一个最终秩为 p。
  2. target<p 时目标不在 p 及右侧;target>p 对称。
  3. 区间严格缩小且从不排除 target,命中时返回正确。

复杂度

TimeSpaceParameters
随机 pivot 期望 O(n),最坏 O(n²)原地迭代 O(1);示例复制输入 O(n)n 为元素数,k 为 1-based;重复值影响平衡。

边界条件

错误模式

PatternWhy it fails / fix
k 下标错位第 k 小 target=k-1;第 k 大 target=n-k。
partition 契约与边界不一致先固定 [lo,hi]、等号去向和 pivot 最终位置。
像 Quicksort 搜两侧只保留含 target 的一侧,否则失去选择优势。
固定恶劣 pivot有序输入可 O(n²);用随机化或更稳健选点。

选择与排除规则

相关模板

RelationTemplateBoundary
specialization分治:拆分、递归、合并partition 后只保留目标秩所在一侧。
alternativeTop-K 有界堆在线、k 小或不能改输入。
alternative双堆维护数据流中位数中位数随插入持续更新。

原创微型例子

环节内容
Result下一轮定位 4,无需完整排序。
Setup读数 [8,2,6,4],求第 2 小。
Tracepivot=6 后 p=2;target=1,只保留左侧 [2,4]。

Recall prompts

我的补充