当前位置:编程学习 > 网站相关 >>

顺序统计学总结

 
先来看一个问题:“给定一个无序的序列,求序列的中位数。”
正常的答案都是“先排序,再取A[n/2],花费O(nlgn)”,学习完本文后,发现其实能够在O(n)求出中位数。
但是要注意,有些场景下前一种方法更好,比如说:“要分别求第1个顺序统计量、第二个顺序统计量、第三个顺序统计量、....、第n个顺序统计量”,如果使用“先排序后取”的方法只要 O (nlgn),但是后一种方法,则要O(n^2)(n次select方法)。
 
顺序统计学要解决的问题是:“给定一个无序序列,问第k个小的数是什么?”
顺序统计学的算法是基于快速排序的partition函数,并运用了分治法的思想。
第i个顺序统计量:第i个最小的值。
 
本文将结合一些习题以便更好地讲解本主题。
 
伪代码:
 
最坏情况运行时间: O (n^2)
最好情况运行时间: O (1)
期望运行时间: O (n)
 
算法导论9.2-1中问:“对于上面的randomized_select,一定不会出现长度为0的递归调用”,因为在randomized_select中,我们的目的要求出第i个顺序统计量,因为调用randomized(A,a,b,i),的条件是A[a,...,b]之间一定有第i个顺序统计量,因此如果调用了长度为0的数组,则与条件矛盾。
 
接下来要证明为什么期望运行时间是 O (n)。
(下述证明需要假设所有元素都是不相同的)
设随机变量T(n)表示select算法的运行时间,E(T(n))表示select算法的期望运行时间。
我们假设按照最坏情况来讨论,即如果划分了两个子数组后,都调用较长的那个子数组。
 
T(n)所有的情况如下图所示:
 
通过替换法即可证明E(T(n))=O(n)
 
 
而上面导致最坏情况出现的原因是randomized_partition的不确定性,怎么样能够得到一个好的划分呢?
Blum、Floyd、Pratt、Rivest、Tarjan发现了一个最坏情况还是线性时间的选择算法。
 
这个算法的基本思想是:每次找到的都是一个好的划分,这样就能保证select的时间是O(n)。具体细节可以看算法导论9.3节,这里我要提一些书上没有的:
(1)书上说的“分组,每组5个元素”,此处每组5个元素是最低要求,即只要大于等于5都可以,但是如果每组4个元素,则划分就不是一个好划分。
算法导论9.3-1中就需要证明如果每组3个元素,select就不是线性时间的了。
 
总结一句话:其实这个算法我们只要把他当做一个封装的子程序来用就可以了:“select(A,p,q,i)方法一定能够在线性时间找出A[p...q]中第i个小的元素。”
 
百度面试题:假设一整型数组存在若干正数和负数,现在通过某种算法使得该数组的所有负数在正数的左边,且保证负数和正数间元素相对位置不变。时空复杂度要求分别为:O(n)和O(1)
 
 
 
 
 
补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,