1 line
18 KiB
JSON
1 line
18 KiB
JSON
|
|
{"content":"所有测试通过 ✅。下面是完整分析:\n\n---\n\n## 时间复杂度详解\n\n### 核心公式:递推关系\n\n每次划分把数组切成两部分,设 pivot 最终位置把 `n` 个元素分成 `k` 和 `n-k-1` 两部分:\n\n$$T(n) = T(k) + T(n-k-1) + \\Theta(n)$$\n\n其中 $\\Theta(n)$ 是分区(partition)的开销——每个元素都要和 pivot 比较一次。\n\n### 三种情况\n\n| 情况 | 条件 | 递推式 | 结果 |\n|------|------|--------|------|\n| **最好** | 每次 pivot 恰好是中位数,均分 | $T(n)=2T(n/2)+\\Theta(n)$ | $\\Theta(n \\log n)$ |\n| **平均** | pivot 随机分布 | $T(n)=\\frac{1}{n}\\sum_{k=0}^{n-1}[T(k)+T(n-k-1)]+\\Theta(n)$ | $\\Theta(n \\log n)$ |\n| **最坏** | 每次 pivot 是最大/最小值,一边为空 | $T(n)=T(n-1)+\\Theta(n)$ | $\\Theta(n^2)$ |\n\n### 直观理解\n\n**最好/平均情况** — $O(n \\log n)$:\n\n```\n每层处理 n 个元素\n┌─────────────────────────┐ ← 第0层: n\n│ partition O(n) │\n├───────────┬─────────────┤\n│ 左 n/2 │ 右 n/2 │ ← 第1层: n\n├─────┬─────┼─────┬───────┤\n│ n/4 │ n/4 │ n/4 │ n/4 │ ← 第2层: n\n└─────┴─────┴─────┴───────┘\n ...共 log₂n 层...\n\n总工作量 = n × log₂n = O(n log n)\n```\n\n**最坏情况** — $O(n^2)$:\n\n当数组已经有序(或逆序)且总选最左/最右作 pivot 时:\n\n```\npivot=1: [1] + 处理 [2,3,...,n] ← 比较 n 次\npivot=2: [2] + 处理 [3,...,n] ← 比较 n-1 次\n...\n总和 = n + (n-1) + ... + 1 = n(n+1)/2 = O(n²)\n```\n\n### 为什么随机化能救回来?\n\n```python\nrand_idx = random.randint(low, high)\narr[rand_idx], arr[high] = arr[high], arr[rand_idx]\n```\n\n随机选 pivot 后,**无论输入是什么**,期望时间复杂度都是 $O(n \\log n)$。因为随机排列下,pivot 的排名等概率落在任何位置,递归树期望深度为 $O(\\log n)$。\n\n### 空间复杂度\n\n| 版本 | 空间 | 说明 |\n|------|------|------|\n| 简洁版(新建数组) | $O(n \\log n)$ | 每层都创建新数组 |\n| 原地版 | $O(\\log n)$ | 递归调用栈深度 |\n| 原地版最坏 | $O(n)$ | 完全偏斜时栈深度=n |\n\n### 与归并排序对比\n\n| | 快速排序 | 归并排序 |\n|------|----------|----------|\n| 时间 | 平均 $O(n \\log n)$,最坏 $O(n^2)$ | 稳定 $O(n \\log n)$ |\n| 空间 | **$O(\\log n)$** | $O(n)$(需辅助数组) |\n| 稳定性 | 不稳定 | 稳定 |\n| 缓存友好 | **好**(顺序访问) | 一般 |\n| 实际速度 | **更快**(常数因子小) | 较慢 |\n\n> 💡 **一句话总结**:快排快在常数因子小 + 缓存友好 + 原地操作,随机化后在实际应用中几乎不会遇到最坏情况,所以成为大多数标准库 `sort` 的默认选择。","iterations_used":3,"tool_calls_made":2,"truncated":false,"session_id":"fe1921f4-d935-491a-8db6-8338ac8c5c64","agent_id":"bdf92fae-27b6-4bfc-8f6a-fdea80d3c0ac","steps":[{"iteration":1,"type":"think","content":"## 快速排序(Quick Sort)\n\n快速排序是分治思想的经典代表,核心步骤:\n1. **选基准(pivot)** → 从数组中挑一个元素\n2. **分区(partition)** → 小于 pivot 放左边,大于放右边\n3. **递归** → 对左右子数组重复上述过程\n\n### 代码实现","tool_name":"code_execute","tool_input":{"code":"\nimport random\nfrom typing import List\n\ndef quicksort(arr: List[int]) -> List[int]:\n \"\"\"快速排序(简洁版,返回新数组,易理解)\"\"\"\n if len(arr) <= 1:\n return arr\n pivot = arr[len(arr) // 2]\n left = [x for x in arr if x < pivot]\n mid = [x for x in arr if x == pivot]\n right = [x for x in arr if x > pivot]\n return quicksort(left) + mid + quicksort(right)\n\n\ndef partition(arr: List[int], low: int, high: int) -> int:\n \"\"\"Lomu
|