我正在考虑解决一个问题的不同方案。假设我们有K个已排序的链表,我们将它们合并成一个链表。所有这些链表一共有N个元素。
众所周知的解决方案是使用优先队列,并从每个列表中弹出/推入第一个元素,我能理解为什么它需要O(N log K)的时间。
但是让我们看看另一种方法。假设我们有一个MERGE_LISTS(LIST1,LIST2)过程,它合并两个排序的列表,这将需要O(T1 + T2)的时间,其中T1和T2代表LIST1和LIST2的大小。
现在我们通常意味着将这些列表配对并逐对合并它们(如果数量是奇数,则可以在最初的步骤中忽略最后一个列表)。这通常意味着我们必须制作以下合并操作的“树”:
N1,N2,N3 ... 表示LIST1,LIST2,LIST3的大小
O(N1 + N2)+ O(N3 + N4)+ O(N5 + N6)+ ...
O(N1 + N2 + N3 + N4)+ O(N5 + N6 + N7 + N8)+ ...
O(N1 + N2 + N3 + N4 + .... + NK)
显然会有log(K)行,每行实现O(N)操作,因此MERGE(LIST1,LIST2,...,LISTK)操作的时间实际上等于O(N log K)。
我的朋友(两天前)告诉我它需要O(KN)的时间。所以问题是-我是否出了问题,还是他实际上是错的?如果我是对的,为什么无法使用这种“分治”方法代替优先队列方法?
众所周知的解决方案是使用优先队列,并从每个列表中弹出/推入第一个元素,我能理解为什么它需要O(N log K)的时间。
但是让我们看看另一种方法。假设我们有一个MERGE_LISTS(LIST1,LIST2)过程,它合并两个排序的列表,这将需要O(T1 + T2)的时间,其中T1和T2代表LIST1和LIST2的大小。
现在我们通常意味着将这些列表配对并逐对合并它们(如果数量是奇数,则可以在最初的步骤中忽略最后一个列表)。这通常意味着我们必须制作以下合并操作的“树”:
N1,N2,N3 ... 表示LIST1,LIST2,LIST3的大小
O(N1 + N2)+ O(N3 + N4)+ O(N5 + N6)+ ...
O(N1 + N2 + N3 + N4)+ O(N5 + N6 + N7 + N8)+ ...
O(N1 + N2 + N3 + N4 + .... + NK)
显然会有log(K)行,每行实现O(N)操作,因此MERGE(LIST1,LIST2,...,LISTK)操作的时间实际上等于O(N log K)。
我的朋友(两天前)告诉我它需要O(KN)的时间。所以问题是-我是否出了问题,还是他实际上是错的?如果我是对的,为什么无法使用这种“分治”方法代替优先队列方法?
N
定义了所有列表中元素的总数,而不是其中一个列表的平均元素数量。 - M. Williams