计算机考研补充知识数据结构相关 | 青训营笔记

54 阅读3分钟

在数据结构的题目中,经常会需要求出数组中第几大或第几小的元素,这种问题叫做选择问题。在一个由nn个元素组成的集合中,第ii顺序统计量定义为该集合中第ii小的元素,选择问题就是给定数组求解第ii顺序统计量的问题。今天我们先讨论最简单的情况。

最值:最小值与最大值在求解上是同理的,这里我们以最小值为例。一般我们都可以想到暴力解法,遍历数组并记录当前的最小元素。这个方法比较次数是n1n-1,时间复杂度为O(n)O(n),看着复杂度有些高,有没有代价更小的方法呢?实际上经过思考我们就会想到是没有的,这就是最优解。因为我们必须要保证数组里的每一个元素都至少被比较过一次,绝对不能有遗漏,因此至少我们要遍历一遍数组,这样时间复杂度最起码就是O(n)O(n)级别,所以这就是最简单代价最小的方案了。

不过对这个问题而言我原来有一个想法,可以类似快速排序的分治思想,两两比较递归操作,这样有没有可能时间复杂度会更低呢?至于这里为什么要选择两两比较而不是三个或多个为一组,首先三个元素一组的话就相当于是一个两元素组加一个一元素组,得出最值需要比较两次,而两两分组比较四个元素也只需要两次,这样很明显两元素组要比三元素组效率更高;至于同一组更多的情况也是同理,那就相当于是把多个两元素组或多个两元素组加一个一元素组分到了一组,并没有完成分治,还是可以继续拆分的。这个问题就是分治的思想出了问题,没有分到最简的情况,所以我认为两元素组是效率最高的。

这样分组完成,计算复杂度,分治第一层需要比较n/2n/2次,第二层需要比较n/4n/4次,这样直到最后共需要log2nlog_2n层,这里是一个等比数列求和,可以计算出比较次数最后的答案为n1n-1,实际上跟一开始的暴力解法的效果是一样的。根据我们最开始的思考也可以证明这一点,至少每个元素都要比较过一次,所以无论怎么分组代价是不变的,不存在通过分组可以跳过某些元素不比较的情况。

这里我们讨论了求解最大值或最小值的选择问题。数据结构问题难点不在于方法的构造,至少我们可以选择暴力求解,难点在于对方法的选择,选择出代价相对小的方案从而简化题目的求解过程。