芋泥奶酪包

导航

算法第二章——分治算法实践

1.用伪代码描述找第 k 小的数的分治算法
该算法又称快速选择(Quickselect),基于分治思想,借助partition划分函数实现。
算法思想(自然语言):
在当前数组区间选取一个基准元素 pivot,调用划分函数将区间划分:所有小于等于 pivot 的元素放在左侧,大于等于 pivot 的元素放在右侧,pivot 落在它在有序数组的正确位置 pos。对比 pos 与 k:
如果 pos 等于 k,pivot 就是第 k 小元素;
如果 pos 大于 k,第 k 小元素在左区间,递归搜索左半边;
如果 pos 小于 k,第 k 小元素在右区间,在右区间寻找第“k-pos”小元素。
伪代码:// 主函数:在数组arr[l...r]中找第k小元素(下标从1计数) function findKthSmallest(arr, l, r, k): if l == r: return arr[l] pos = partition(arr, l, r) if pos == k: return arr[pos] else if pos > k: return findKthSmallest(arr, l, pos - 1, k) else: return findKthSmallest(arr, pos + 1, r, k - pos) // 划分函数partition function partition(arr, l, r): pivot = arr[r] i = l - 1 for j from l to r - 1: if arr[j] <= pivot: i = i + 1 swap arr[i], arr[j] swap arr[i+1], arr[r] return i + 1

2.算法时间复杂度分析
最好时间复杂度O(n):每次划分能够将数组近似对半拆分,递推式T(n)=T(n/2)+O(n)。根据主定理,得到最好时间复杂度为O(n)。
最坏时间复杂度O(n^2):每次选取的基准都是当前区间的最大值或最小值,划分后一侧仅保留 1 个元素。递推式T(n)=T(n-1)+O(n),累加计算得到最坏时间复杂度O(n^2)。

3.对分治法的体会和思考
分治法的核心是“分解子问题-求解子问题-合并子问题”:把规模较大的原问题,拆分成多个结构相同、规模更小的子问题;递归求解各个子问题;最后合并子问题结果,得到原问题的解。
寻找第 k 小元素这个例子,让我体会到分治思想不是固定模板,存在灵活的变体。像归并排序这类经典分治算法,需要求解全部子问题再合并结果;而快速选择不需要同时处理左右两个子区间,只递归目标元素所在的一侧,省去不必要的计算,提升效率。
分治的优势很明显:递归实现逻辑清晰,把复杂大问题拆解成简单小问题,降低问题理解难度,并且天然适合并行计算。但分治也有局限:递归会带来栈空间开销,递归深度过大容易栈溢出;算法性能严重依赖划分策略,基准选择不合适时,算法效率会急剧退化。
本章学习让我意识到,分治是一种解决问题的思维,而不是单纯的代码模板。遇到复杂问题,首先可以思考是否可以拆分为同类型的子问题;但不能盲目套用分治,需要结合问题特性选择划分方式,权衡时间、空间开销。

posted on 2026-10-13 23:06  芋泥奶酪包  阅读(4)  评论(0)    收藏  举报