如何不排序求中位数?
虽然有人提过用快排的思想来实现,但一时脑子仍然没想到,后来查了资料,分享这样一篇
分析:中位数的特点:前面的数比他小,后面的数比他大
中位数即是排过序后的处于数组最中间的元素。 不考虑数组长度为偶数的情况。设集合元素个数为n。
简单的想了下:
思路1) 把无序数组排好序,取出中间的元素
时间复杂度 采用普通的比较排序法 O(N*logN)
如果采用非比较的计数排序等方法, 时间复杂度 O(N), 空间复杂度也是O(N).
思路2)
2.1)将前(n+1)/2个元素调整为一个小顶堆,
2.2)对后续的每一个元素,和堆顶比较,如果小于等于堆顶,丢弃之,取下一个元素。 如果大于堆顶,用该元素取代堆顶,调整堆,取下一元素。重复2.2步
2.3) 当遍历完所有元素之后,堆顶即是中位数。
思路3) 熟话说,想让算法跑的更快,用分治!
快速排序之所以得名"快排",绝非浪得虚名!因为快排就是一种分治排序法!
同样,找中位数也可以用快排分治的思想。具体如下:
任意挑一个元素,以改元素为支点,划分集合为两部分,如果左侧集合长度恰为 (n-1)/2,那么支点恰为中位数。如果左侧长度<(n-1)/2, 那么中位点在右侧,反之,中位数在左侧。 进入相应的一侧继续寻找中位点。
这种方法很快,但是在最坏的情况下时间复杂度为O(N^2), 不过平均时间复杂度好像是O(N)。