算法导论的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⌋。
其实,上述方法中所做的所有比较的集合, 与算法导论作者的方法所做的比较的集合是相同的。