大四下学期买了一本《数据结构与算法分析—C语言描述》,由于当时也快毕业了,哪还有学习的心思啊,所以看了几页就没耐心了,它就被束之高阁了。幸好,毕业时没把它当废书处理了而是把它带到了工作的地方,时隔两年,再次翻阅,甚是后悔啊,后悔“为什么当时没能读下去”。
开篇就有一个选择问题“设有一组N个数而要确定其中第k个最大者”。
针对这个问题,相信很多人都会想到以下思路:将这N个数读进一个数组中,再通过某种简单的算法,比较冒泡排序法,以递减顺序将数组排好序,然后返回位置k上的元素。
比这个稍微好点的算法是:先把前k个元素读入数组(以递减的顺序)对其排序,然后接剩下的元素再逐个读入,当新元素被读到时,如果它小于数组中的第k个元素则忽略,否则就将其放到数组中正确的位置上,同时将数组中的一个元素挤出数组。当算法终止时,位于第k个位置上的元素作为答案返回。
这两种算法的编码都还不复杂,但是我们会问:哪个算法更好?哪个算法更重要?还是两个算法足够好。使用含有一百万个元素的随机文件,在k=500000的条件下进行模拟发现,每种算法都需要计算机处理若干天才能计算完(我并没有模拟,这是作者的说明),这显然不是我们想要的结果。当然,在此问题中,空间复杂度显得不是那么重要了。但是,时间复杂度却异常重要。当我们分析时间复杂度时,我们需要的是最坏情况下的运行时间。这有两方面的原因:其一,它 对所有的输入提供了一个界限,包括特别坏的输入,而平均情况分析不提供这样的界限;其二,平均情况的界计算起来通常要困难得多。
最大的子序列和问题:给定整数A1,A2,…,AN(可能有负数),求的最大值(为了方便起见,如果所有整数均为负数,则最大子序列和为0)。
例如,输入 -2,11,-4,13,-5,-2时,答案为20(从A2到A4)。
这个问题之所以有吸引力,是因为求解它有很多解法,而不同解法的时间复杂度又相差甚远!