算法第二章实践作业
1、自然语言描述:找第k小(快速选择,分治)
先用partition函数,传入数组a以及left和right,以x=a [left]为基准,用一个大循环(满足i<j)将数组划分成两部分,左边所有元素小于等于基准,右边所有元素大于等于基准。
具体做法是:
用一个外部的大循环,嵌套两个小循环,第一个小循环先从右往左找,满足i<j且a[j]<=x的时候,将此时的a[j]赋值给a[i],然后第二个小循环从左往右找,找出比基准大的数,将此时的a[i]赋值给a[j],不断循环,不断交换,直到i>=j,此时a[i]左边所有元素小于等于基准,右边所有元素大于等于基准,最后将基准赋值给a[i],返回此时下标i。
找出第k小的数是用find的函数来实现,传入数组a,左右下标和k。
具体做法是:
调用partition函数得到基准的下标p,计算基准在当前区间是第 rank = pos-left+1小。
通过rank和k比较分三种情况讨论:
若rank = k:基准就是答案,返回 a [p]
若rank > k:目标在左半区间,递归在[left, pos-1]找第k小
若rank < k:目标在右半区间,递归在[pos+1, right]找第k−rank小,因为是在右边区间找,所以要去掉包括基准的前面的数。
2、时间复杂度分析
最好情况O (n)
每次partition划分,基准刚好落在区间中间,左右两部分大致均分。每次递归只需要处理一半区间。
最坏情况 O (n²)
每次选的基准都是当前区间最大/最小元素,划分极度不均衡,一边只有 1 个元素,另一边剩下全部元素。例如数组已经有序,每次选最左当基准。
3、对分治法的体会和思考
分治法的核心思想是分、治、合:把一个规模大的原问题,分解成若干结构相同、规模更小的子问题;然后递归求解子问题;最后把子问题的解合并,得到原问题的解。
浙公网安备 33010602011771号