第二周作业
一、找第 k 小的数的分治算法描述(伪代码 + 自然语言)
核心结论:分治算法通过 “选基准→分区→递归缩小范围”,无需全排序即可找到第 k 小的数,伪代码简洁且执行高效。
伪代码
plaintext
function findKthSmallest(arr, left, right, k):
if left == right: # 子数组仅1个元素,直接返回
return arr[left]
# 1. 选基准(此处选右边界元素,也可随机选)
pivotIndex = partition(arr, left, right)
# 2. 计算基准元素是当前子数组的第m小(m = 基准左侧元素个数 + 1)
m = pivotIndex - left + 1
# 3. 分情况递归
if m == k:
return arr[pivotIndex] # 基准恰好是第k小,直接返回
elif m > k:
# 第k小在基准左侧,递归左子数组
return findKthSmallest(arr, left, pivotIndex - 1, k)
else:
# 第k小在基准右侧,递归右子数组(k更新为k - m)
return findKthSmallest(arr, pivotIndex + 1, right, k - m)
分区函数:将数组按基准划分,左侧≤基准、右侧≥基准,返回基准最终位置
function partition(arr, left, right):
pivot = arr[right] # 基准元素
i = left - 1 # i指向“左侧区域末尾”
for j from left to right - 1:
if arr[j] ≤ pivot:
i += 1
swap(arr[i], arr[j]) # 把≤基准的元素移入左侧区域
swap(arr[i + 1], arr[right]) # 基准放到最终位置(左侧区域之后)
return i + 1 # 返回基准索引
自然语言解释
终止条件:如果当前处理的子数组只有 1 个元素,这个元素就是目标(第 k 小)。
分区操作:选一个基准元素(如子数组最后一个元素),通过交换将数组分成两部分 —— 左侧元素都≤基准,右侧元素都≥基准,最后返回基准的最终位置。
确定范围:计算基准元素在当前子数组中的 “排名” m(左侧有 m-1 个元素,所以基准是第 m 小)。
递归处理:若 m=k,基准就是答案;若 m>k,第 k 小在左侧子数组,递归左侧;若 m<k,第 k 小在右侧子数组,递归右侧(此时 k 需减去左侧元素总数 m)。
二、算法时间复杂度分析
最好时间复杂度:O (n)
关键前提:每次分区后,基准元素恰好将数组分成 “大小均衡的两部分”(如左右子数组长度相差不超过 1)。
分析逻辑:第一次分区处理 n 个元素,第二次处理 n/2 个,第三次 n/4 个,总操作次数为 n + n/2 + n/4 + ... + 1 ≈ 2n,因此时间复杂度为 O (n)。
最坏时间复杂度:O (n²)
关键前提:每次分区后,基准元素是当前子数组的 “最值”(如每次选到最小或最大元素),导致子数组规模仅减少 1。
分析逻辑:第一次分区处理 n 个元素,第二次 n-1 个,第三次 n-2 个,总操作次数为 n + (n-1) + (n-2) + ... + 1 = n (n+1)/2,因此时间复杂度为 O (n²)。
三、对分治法的体会和思考
- 分治法的核心思想
分治法的本质是 “化繁为简”,将一个大规模、复杂的问题,拆解成多个规模更小、结构相同的子问题,递归解决子问题后,无需额外合并(或少量合并)即可得到原问题答案。它的核心是 “分”(拆解问题)和 “治”(解决子问题),关键在于 “如何分”—— 拆分后的子问题必须与原问题同构,且拆分后能显著降低问题难度。 - 分治法的优势与适用场景
优势:无需处理整个问题空间,仅聚焦关键子问题(如找第 k 小无需全排序),效率远高于暴力法;递归结构清晰,代码易实现、易理解。
适用场景:问题可拆分为同构子问题、子问题独立无依赖、子问题解决后可快速组合出原答案(如排序、查找、矩阵乘法等)。 - 分治法的注意事项
拆分均衡性是效率关键:如找第 k 小的算法,若分区均衡则时间复杂度 O (n),若不均衡则退化为 O (n²),因此实际应用中常 “随机选基准” 优化均衡性。
避免重复计算:部分问题(如斐波那契数列)直接分治会产生大量重复子问题,需结合动态规划或记忆化搜索优化。
递归深度控制:极端情况下递归深度可能达到 O (n)(如最坏情况的找第 k 小算法),可能导致栈溢出,可通过迭代改写或尾递归优化。 - 分治法的本质启发
分治法体现了 “整体与部分” 的辩证关系 —— 复杂问题的解往往蕴含在其部分子问题的解中。它不仅是一种算法设计技巧,更是一种解决问题的思维方式:面对复杂任务时,先拆解为可落地的小任务,逐个突破后再整合,既降低了单个任务的难度,也便于并行处理或分步优化。

浙公网安备 33010602011771号