数据结构王道考研书的绪论的统考真题:两个升序列表合并的最坏情况的时间复杂度

题目描述:

已知两个长度分别为m和n的升序列表,若将它们合并为一个长度为m+n的降序列表,则最坏情况下的时间复杂度是(D)

A. O(n)
B. O(mn)
C. O(min(m,n))
D. O(max(m,n))

关于这题,我先看过一些博客,最后又加上自己的思考,最终进行梳理:

核心是:分别设置两个指针指向两个列表的第一个元素,然后进行比较,更小的就拎出来放在一个新的列表中,之后指针后移一位,以此类推

  • 注意:将一个列表逆置的时间复杂度是 O(列表的长度)

首先, 先思考一下最好的情况是怎样的呢?

不难想到,就是第一个列表的最后一个数 会 小于等于 第二个列表的第一个数,且第一个列表长度更小,这样就让比较次数达到最少,如:

列表 A: 1  2  3
列表 B: 4  5  6  7  8  9

这样可以容易得到,列表B的第一个数“4”,依次和列表A的数进行比较,则结果是O(min(m,n))

可以看出,思路就是怎么样能使得比较次数最少,就是最好的情况,而这个情况就是使得更短的列表的最后一个数被比较到了。


那反过来,最坏的情况,不就是使得比较次数最多吗?

怎样能使得比较次数最多呢?可能会想那不就是最长的列表的最后一个数被比较到了,如下,列表A的第一个数“10”不断地和B中的所有数进行比较:

列表 A: 10  11  12
列表 B: 4  5  6  7  8  9

但是,这真的是最坏的情况吗,为什么不干脆让两个列表的最后一个数都进行了比较呢?这样比较次数不是更多吗?比如说(假设a<b,不就存在 a<b<a+b 吗?),如下图:

列表A:1   100
列表B: 2  3  4  5  6 7  8  9  10  11  12  13  14  15  16  17  18  ..... 101

上面这种情况,就是列表A的“1” 先和 列表B的“2”进行比较,之后从 列表B的 “2”~“100”都和列表A的最后一个数“100”进行比较,最后列表B的最后一个数“101”再和列表A的“100”进行比较。

总共比较次数是:1+(100-2+1)+1=101 次 (也可以自己再多想几个例子,下面会讲解为什么这样是比较次数最多的情况)

列表A长度为2,列表B长度为 100 ,则 m+n=102,比较次数为 m+n-1 = 101次。

选项中没有O(m+n),我们可以再继续思考,计算时间复杂的有一个加法规则

在这里插入图片描述
那么T(n)=O(m)+O(n)=O(max(m,n))不是就可以成立了吗?(O(1)忽略不计),或者换一个角度想:

假设m=2,n不止等于100呢,等于1000,10000, 100000000000呢?那么当n很大很大的时候,加了2和没有2又有什么区别呢?

所以,最后答案是D。


写这个题目的时候,我发现答案解析很简洁,就是说,最差情况是两个列表的数依次比较

又找了一些博客看,有说是两个列表相互交错,都让我有一些没反应过来。

后面自己想清楚了才知道,就是指:(看下面的代码)a1<=b1,a5<=a8,这样的话,a1 (列表A的首)和a8(列表B的尾)一定在新的列表的两端,那么这两个列表其余的数(a1之后的数 和 b8之前的数)怎么可能不进行依次比较呢?

列表A: a1  a2  a3  a4  a5
列表b:   b1  b2  b3  b4  b5  b6  b7  b8

这样的话无论怎样都会进行交错(极端的情况就是上面的例子,列表B的前99个数都>=1, 且<= 100,最后一个数一定大于100,这样形成了交错

写下这按文章,是因为觉得自己看了很多思路又思考了很久后,最终想出的思路还挺好理解的,也想记录下自己的思考,哪怕只是一个很小的问题,很小的点,也能为接下来的复习增添动力。如有觉得这篇文章有任何疑问或不正确,欢迎指正!

猜你喜欢

转载自blog.csdn.net/weixin_47505105/article/details/123413366