434
社区成员
发帖
与我相关
我的任务
分享已知一无序数列,找第k小的数。以下是该题算法的自然语言描述。
一,我们以数列中随机某个数为基准元素(通常是以左边第一个数)。
二,使用快速排列,让数列中,该数左边的数都小于等于基准元素,右边的数都大于基准元素。
三,将排列后基准元素的位置(假设为n)与k进行比较:
若n>k,则用基准左半边数列作为新的无序数列,重复1~3的操作;
若n>k,则用右半边数列作为新的无序数列,重复1~3的操作;
当n等于k的时候,则结束递归,输出基准元素。
最好时间复杂度:O(n)。最好情况下,每次选择的基准都是数列的中位数,又因为找到第k个数就可以结束递归,所以最好时间复杂度是O(n)。
最坏时间复杂度:O(n^2)。第k个数是最大的数或者最小的数,并且每次选择的基准都分配非常不平均的情况,所以最坏时间复杂度是O(n^2)。
分治法,本质是将原问题分成数个更小的子问题,解决那些子问题,然后将它们合并成原问题答案的过程。该过程分成三个阶段,分解原问题,解决子问题,合并子问题。要注意,在计算时间复杂度时,分解原问题和合并子问题这两个步骤,也要计算其中。
在编程时,我们通常用递归或者其他方法,将分解后的子问题,再分解成更小的子问题。通过不断分解,直到子问题足够小,能够简单解决后,再逐步往上合并解决更大的子问题……直到解决原问题。
分治法的局限性在于,子问题类型必须与原问题完全相同。并不是所有的问题都可以用分治法。
*本章学了二分法的一种使用方法:左右逼近,求满足题目(分配要求or截取要求)的最优数。