同时获得一个序列的最小和最大值的方法

来源:互联网 发布:ubuntu系统官网 编辑:程序博客网 时间:2024/04/28 21:30

算法导论的9.1Minimum and maximum 提到了可以同时获得一个序列的最小和最大值,而且最多使用 3 n/2的时间。

作者阐述了取得的方法。

这里,本人也有一个思路。这个思路类似于比赛的分组。

假设n=2k,这样并不影响分析。

 

序列示例: {10,3,14,5,7,11,2,8,13,6,9,1,15,4,12,16}

 

1. 相邻两元素两两比较,即 第i项 与 i+1项比较, i = 1,3,5,...,n-1

   i 与 i+1中较小者进入smaller team(1), 较大者进入larger team(1):

   smaller team(1) = {3,5,7,2,6,1,4,12}

   larger team(1)   = {10,14,11,8,13,9,15,16}

 

 共计时间total time = n/2

 

2. smaller team(1) 元素进行相邻两元素的两两比较,

    但我们对于smaller team(1)的比较,目的只在于进一步“过滤”出更小的元素,

    从而得到smaller team(2), 而不需要分成2个组。从而,只保留比较后的

    smaller team(2) = {3,2,1,4}

    由于总共smaller team(1)有n/2个元素,所以两两比较,时间为n/4

 

    同理,对larger team(1)元素进行相邻两元素的两两比较,

   “过滤”出更大的元素,组成

    larger team(2) = {14,11,13,16}

    时间也为n/4

 

 共计时间total time = 2*n/4=n/2

 

3.与2类似,继续递归进行两两比较,

   由smaller team(2) 生成 smaller team(3)={2,1}花费n/8

   由larger team(2) 生成 larger team(3)={14,16}也花费n/8

共计时间total time = 2*n/8=n/4;

 

   由smaller team(3) 生成 smaller team(4)={1}花费n/16

   由larger team(3) 生成 larger team(4)={16}也花费n/16

共计时间total time = 2*n/16=n/8;

 

在本例,n=16,所以n/8=2,此时问题已经解决。

 

 

一般的,除了最初生成smaller team(1)与larger team(1)花费的n/2时间以外,

其他的smller team(1)->....->smaller team(lgn)

        larger team(1)->....->larger team(lgn)

每一步分别花费时间:

n/2,n/4,n/8,...,4,2;

共花费时间 = (n/2*2-2)/(2-1) = n/2 - 2 (等比数列n项和公式)

 

那么总共花费时间 = n/2 + n - 2 = 3*n/2 - 2

 

得到总共花费时间 =3 n/2⌋。

 

其实,上述方法中所做的所有比较的集合,与算法导论作者的方法所做的比较的集合是相同的。