最大的数和最小的数、最大的两个数
恰当安排可以减少比较次数,见下。
求序列中最大数和最小数的时候,naive的做法(分别求)需要比较大约2n次。
更好的做法是:假设易知max和min是前k个元素的最大和最小,那么,将k+1与k+2先比较一下,然后,大的和max比,得到新的最大;小的和max比,得到新的最小。这样,每向后走两个元素,只需要三次比较,最终的比较次数大约是3n/2次。
求序列中最大的两个数,可以这么做:假设max1, max2是一个子集A的最大和次大元素,max3, max4是另一个子集B的最大和次大元素,那么,Union(A, B)的最大元素只可能是max1和max3中比较大的一个,假设max1>max3,那么次大元素只可能是max2和max3中的一个,而max4肯定已经落选了。因此,max4就不需要参与比较了。
有鉴于此,对于每次分治,可以对每个子集维护一个最大的元素和可能的第二大元素的集合,这样比较的时候,类似于上例中的max4集合就可以直接扔掉,不参与后续的比较。
这个第二大元素的候选集合,最终元素个数应该是logn级别的,之后,在这个候选集合里面走一遍,就得到第二大的元素了。