第二章时间作业

一、分治算法
以快速排序为例:
1.在数组里随便选一个数当做基准值pivot
2.划分:把数组分成两部分,左边所有数字<=pivot,右边所有数字>=pivot。划分完成后,pivot就处在它在有序数组里的正确位置,假设它的下标是pos
3.分情况判断:
如果pos==k-1 数组下标从0开始 pivot就是第k小元素,直接返回。
如果pos>k-1 第k小的数一定在左边区间,只递归处理左半部分。
如果pos<k-1 第k小的数一定在右边区间,我们要找右边区间里第k-pos-1小的数,递归处理右半部分
二、时间复杂度分析
最好时间复杂度:O(n)
每次划分的时候,基准值刚好把数组切成差不多两半。每次处理的数组长度不断减半 n+n/2+n/4+...=O(n)
最坏时间复杂度:O(nn)
每次选的基准值都是当前区间的最大值或者最小值,划分后一边只有 1 个元素,另一边是剩下全部元素。需要递归n层,总运算量 n+(n-1)+(n-2)+...=O(n
n)
随机选基准值的时候,平均复杂度是O(n)
三、分治法的体会与思考
分治法就是把一个大难题,拆成好几个规模更小的同类问题,把小问题解决完后,再拼回得到大问题的答案,学习完找第k小、快速排序这些例子,我有一些感受:
1.不是所有问题都适合分治。分治要求拆分出来的子问题和原来问题是同一类型,而且子问题之间互不干扰,子问题的结果还能合并出最终答案。如果子问题会重复计算,用分治就会做很多无用功,这种情况就更适合做动态规划。
2.分治不一定两边都要处理。以前我以为分治就一定要把问题分成两半,两个部分都递归求解。但找第k小这个算法告诉我可以灵活处理:我们只关心答案在哪一边,就只递归那一半,另一半直接丢掉不用管,这样可以省下很多计算,提升效率。
3.怎么拆分很关键,拆分的好坏直接影响算法快慢。以找第k小为例,如果每次拆分都能把数组均匀分开,算法跑的就很快。可如果每次拆分一边只有一个元素,另一边一大堆,算法效率就会变得很差。这让我意识到写算法不只要能算出结果,还要考虑最坏情况下的表现。
4.递归实现写起来简单,但也有缺点。分治大多用递归实现,代码逻辑读起来很直观。但递归调用层数太深的时候,程序可能会栈溢出,实际使用的时候也可以改成循环迭代的写法。

posted @ 2026-10-13 22:40  贾思妍  阅读(2)  评论(0)    收藏  举报