大白话解析快排Python

文章目录

把这段代码想象成一个"整理高矮队伍的教官"。教官手头有一排乱糟糟的人,任务是把矮的排左边,高的排右边。


第一步:找一个"裁判",并防范有人"作弊"

python 复制代码
rand_idx = random.randint(l, r)
mid = (l + r) // 2
q[mid], q[rand_idx] = q[rand_idx], q[mid]
x = q[mid]
  • 普通操作 :教官每次都固定挑正中间那个人当身高基准 x x x("比他矮的站左边,比他高的站右边")。
  • 为什么被卡超时? LeetCode 就像一个存心搞破坏的刺头,提前摸清了你每次都选正中间,于是故意排出一个特制队形,让你每次选的中点要么是队伍里最高的,要么是最矮的。结果你每次切队伍只能切下 1 个人,工作量直接爆炸成 O ( n 2 ) O(n^2) O(n2)。
  • 破局妙招(这 3 行代码) :教官在选基准前掷一次骰子 ,从队伍里随机抓一个人换到中间。这下出题人再怎么设计队形也没用,因为你选基准的位置是随机的,每次都能大概率把队伍对半切开,时间稳保 O ( n log ⁡ n ) O(n \log n) O(nlogn)。

第二步:两个侦察兵进场(指针初始化)

python 复制代码
i, j = l - 1, r + 1
  • 左边派一个兵 i i i,右边派一个兵 j j j。
  • 为什么站在边界外面( l − 1 l-1 l−1 和 r + 1 r+1 r+1)?因为教官下达的死命令是:只要开始巡逻,第一件事必须先往前迈一步! 站在场外,一迈步正好踏入合法队伍的第一个和最后一个位置。

第三步:相向而行,互换违规人员

python 复制代码
while i < j:
    while True:
        i += 1
        if q[i] >= x:
            break
    while True:
        j -= 1
        if q[j] <= x:
            break
    if i < j:
        q[i], q[j] = q[j], q[i]
  1. 左兵 i i i 出发 :向右走,只要看到比裁判矮( < x < x <x)的就放行;一旦抓到一个"身高 ≥ x \ge x ≥x 却站在左边"的违规大个子,立刻停下(break)。
  2. 右兵 j j j 出发 :向左走,只要看到比裁判高( > x > x >x)的就放行;一旦抓到一个"身高 ≤ x \le x ≤x 却站在右边"的违规矮个子,也立刻停下(break)。
  3. 现场交换 :如果两人还没撞上( i < j i < j i<j),说明抓到了两个站错方向的家伙,直接把他们对调位置 (q[i], q[j] = q[j], q[i])。
  4. 循环往复 ,直到两个侦察兵擦肩而过( i ≥ j i \ge j i≥j),此时队伍就达到了一个状态:j j j 及 j j j 左边的人,身高全部 ≤ x \le x ≤x; j + 1 j+1 j+1 及右边的人,身高全部 ≥ x \ge x ≥x。

这里为什么用 while True + >= / <=?

如果队伍里有大量"身高一模一样"的人,这个机制能保证 i i i 和 j j j 每次抓到一样高的也会各走一步互换,最后刚好在正中间相遇交错,绝不会卡在同一个位置原地踏步(死循环)。


第四步:任务拆分,递归解决

python 复制代码
qs(q, l, j)
qs(q, j + 1, r)

教官现在发现:队伍已经被 j j j 完美分成了左半段(都不高于 x x x)和 右半段(都不低于 x x x) 。

接下来教官不再管细节,把左半段交给副官 A 去用同样的方法排,右半段交给副官 B 去排。子队伍越拆越小,拆到队伍里只有 1 个人( l ≥ r l \ge r l≥r)时自然就有序了,直接返回。


极简口诀复盘

  1. 随机换中间:掷骰子破定点针对。
  2. 两头向内迈:先走一步再核对。
  3. 违规就交换:矮去左边高去右。
  4. 切分靠 j j j 标:左右分治排到底。
相关推荐
doujiaozh1 小时前
我在 DOS 6.22 上跑通了 Kimi AI:一场跨越 40 年的硬核接力
python
凛铄linshuo1 小时前
分析业务流程什么时候适合断言?
python·pytest
import_random2 小时前
[python]IDE可以自动检测venv工具创建的虚拟环境.venv吗
python
楠风测开2 小时前
Python学习路线:搭好环境,跑通第一个脚本
python
code2cat2 小时前
【随笔】RAG重排怎样挑证据:先扩大候选,再把相关片段排到前面
人工智能·python·大语言模型·rag
云和数据.ChenGuang2 小时前
python大小整数范围解析
java·开发语言·python
cpolar技术支持2 小时前
端口被谁占了、这台机上开了哪些监听?本机起一个端口占用只读清单,cpolar 给异地同事远程看谁在监听
运维·python·内网穿透·cpolar·端口占用
长坡夜行2 小时前
没有运维的交易系统,是怎么自己活下去的
python
WeiXin_DZbishe3 小时前
基于springboot装修风格选择系统的设计与开发-计算机毕设【课程设计】77964
java·vue.js·spring boot·后端·python·php·课程设计