Python程序合并 K 个已排序的链表 – 第 1 组
给定 K 个大小为 N 的已排序链表,将它们合并并打印排序后的输出。
例子:
Input: k = 3, n = 4
list1 = 1->3->5->7->NULL
list2 = 2->4->6->8->NULL
list3 = 0->9->10->11->NULL
Output: 0->1->2->3->4->5->6->7->8->9->10->11
Merged lists in a sorted order
where every element is greater
than the previous element.
Input: k = 3, n = 3
list1 = 1->3->7->NULL
list2 = 2->4->8->NULL
list3 = 9->10->11->NULL
Output: 1->2->3->4->7->8->9->10->11
Merged lists in a sorted order
where every element is greater
than the previous element.
方法1(简单):
方法:
一个简单的解决方案是将结果初始化为第一个列表。现在遍历从第二个列表开始的所有列表。将当前遍历列表的每个节点以排序的方式插入到结果中。
Python3
# Python3 program to merge k
# sorted arrays of size n each
# A Linked List node
class Node:
def __init__(self, x):
self.data = x
self.next = None
# Function to print nodes in a given
# linked list
def printList(node):
while (node != None):
print(node.data,
end = " ")
node = node.next
# The main function that takes an
# array of lists arr[0..last] and
# generates the sorted output
def mergeKLists(arr, last):
# Traverse form second
# list to last
for i in range(1, last + 1):
while (True):
# head of both the lists,
# 0 and ith list.
head_0 = arr[0]
head_i = arr[i]
# Break if list ended
if (head_i == None):
break
# Smaller than first
# element
if (head_0.data >=
head_i.data):
arr[i] = head_i.next
head_i.next = head_0
arr[0] = head_i
else:
# Traverse the first list
while (head_0.next != None):
# Smaller than next
# element
if (head_0.next.data >=
head_i.data):
arr[i] = head_i.next
head_i.next = head_0.next
head_0.next = head_i
break
# go to next node
head_0 = head_0.next
# if last node
if (head_0.next == None):
arr[i] = head_i.next
head_i.next = None
head_0.next = head_i
head_0.next.next = None
break
return arr[0]
# Driver code
if __name__ == '__main__':
# Number of linked
# lists
k = 3
# Number of elements
# in each list
n = 4
# an array of pointers
# storing the head nodes
# of the linked lists
arr = [None for i in range(k)]
arr[0] = Node(1)
arr[0].next = Node(3)
arr[0].next.next = Node(5)
arr[0].next.next.next = Node(7)
arr[1] = Node(2)
arr[1].next = Node(4)
arr[1].next.next = Node(6)
arr[1].next.next.next = Node(8)
arr[2] = Node(0)
arr[2].next = Node(9)
arr[2].next.next = Node(10)
arr[2].next.next.next = Node(11)
# Merge all lists
head = mergeKLists(arr, k - 1)
printList(head)
# This code is contributed by Mohit Kumar 29
Python3
# Python3 program to merge k sorted
# arrays of size n each
# A Linked List node
class Node:
def __init__(self):
self.data = 0
self.next = None
# Function to print nodes in a
# given linked list
def printList(node):
while (node != None):
print(node.data, end = ' ')
node = node.next
# Takes two lists sorted in increasing order,
# and merge their nodes together to make one
# big sorted list. Below function takes
# O(Log n) extra space for recursive calls,
# but it can be easily modified to work with
# same time and O(1) extra space
def SortedMerge(a, b):
result = None
# Base cases
if (a == None):
return(b)
elif (b == None):
return(a)
# Pick either a or b, and recur
if (a.data <= b.data):
result = a
result.next =
SortedMerge(a.next, b)
else:
result = b
result.next =
SortedMerge(a, b.next)
return result
# The main function that takes an array
# of lists arr[0..last] and generates
# the sorted output
def mergeKLists(arr, last):
# Repeat until only one list is left
while (last != 0):
i = 0
j = last
# (i, j) forms a pair
while (i < j):
# Merge List i with List j and store
# merged list in List i
arr[i] = SortedMerge(arr[i], arr[j])
# Consider next pair
i += 1
j -= 1
# If all pairs are merged, update last
if (i >= j):
last = j
return arr[0]
# Utility function to create a new node.
def newNode(data):
temp = Node()
temp.data = data
temp.next = None
return temp
# Driver code
if __name__=='__main__':
# Number of linked lists
k = 3
# Number of elements in each list
n = 4
# An array of pointers storing the
# head nodes of the linked lists
arr = [0 for i in range(k)]
arr[0] = newNode(1)
arr[0].next = newNode(3)
arr[0].next.next = newNode(5)
arr[0].next.next.next = newNode(7)
arr[1] = newNode(2)
arr[1].next = newNode(4)
arr[1].next.next = newNode(6)
arr[1].next.next.next = newNode(8)
arr[2] = newNode(0)
arr[2].next = newNode(9)
arr[2].next.next = newNode(10)
arr[2].next.next.next = newNode(11)
# Merge all lists
head = mergeKLists(arr, k - 1)
printList(head)
# This code is contributed by rutvik_56
输出:
0 1 2 3 4 5 6 7 8 9 10 11
复杂性分析:
- 时间复杂度: O(nk 2 )
- 辅助空间: O(1)。
因为不需要额外的空间。
方法2:最小堆。
更好的解决方案是使用基于 Min Heap 的解决方案,这里讨论了数组。该解决方案的时间复杂度为O(nk Log k)
方法三:分而治之。
在这篇文章中,讨论了分而治之的方法。这种方法不需要额外的堆空间并且工作在 O(nk Log k)
众所周知,两个链表的合并可以在 O(n) 时间和 O(n) 空间内完成。
- 这个想法是配对 K 个列表并使用 O(n) 空间在线性时间内合并每一对。
- 在第一个循环之后,剩下 K/2 个列表,每个列表的大小为 2*N。在第二个循环之后,留下 K/4 个列表,每个列表的大小为 4*N,依此类推。
- 重复这个过程,直到我们只剩下一个列表。
下面是上述思想的实现。
Python3
# Python3 program to merge k sorted
# arrays of size n each
# A Linked List node
class Node:
def __init__(self):
self.data = 0
self.next = None
# Function to print nodes in a
# given linked list
def printList(node):
while (node != None):
print(node.data, end = ' ')
node = node.next
# Takes two lists sorted in increasing order,
# and merge their nodes together to make one
# big sorted list. Below function takes
# O(Log n) extra space for recursive calls,
# but it can be easily modified to work with
# same time and O(1) extra space
def SortedMerge(a, b):
result = None
# Base cases
if (a == None):
return(b)
elif (b == None):
return(a)
# Pick either a or b, and recur
if (a.data <= b.data):
result = a
result.next =
SortedMerge(a.next, b)
else:
result = b
result.next =
SortedMerge(a, b.next)
return result
# The main function that takes an array
# of lists arr[0..last] and generates
# the sorted output
def mergeKLists(arr, last):
# Repeat until only one list is left
while (last != 0):
i = 0
j = last
# (i, j) forms a pair
while (i < j):
# Merge List i with List j and store
# merged list in List i
arr[i] = SortedMerge(arr[i], arr[j])
# Consider next pair
i += 1
j -= 1
# If all pairs are merged, update last
if (i >= j):
last = j
return arr[0]
# Utility function to create a new node.
def newNode(data):
temp = Node()
temp.data = data
temp.next = None
return temp
# Driver code
if __name__=='__main__':
# Number of linked lists
k = 3
# Number of elements in each list
n = 4
# An array of pointers storing the
# head nodes of the linked lists
arr = [0 for i in range(k)]
arr[0] = newNode(1)
arr[0].next = newNode(3)
arr[0].next.next = newNode(5)
arr[0].next.next.next = newNode(7)
arr[1] = newNode(2)
arr[1].next = newNode(4)
arr[1].next.next = newNode(6)
arr[1].next.next.next = newNode(8)
arr[2] = newNode(0)
arr[2].next = newNode(9)
arr[2].next.next = newNode(10)
arr[2].next.next.next = newNode(11)
# Merge all lists
head = mergeKLists(arr, k - 1)
printList(head)
# This code is contributed by rutvik_56
输出:
0 1 2 3 4 5 6 7 8 9 10 11
复杂性分析:
假设 N(n*k) 是节点的总数,n 是每个链表的大小,k 是链表的总数。
- 时间复杂度: O(N*log k) 或 O(n*k*log k)
作为函数mergeKLists() 中的外部 while 循环运行 log k 次,并且每次它处理 n*k 个元素。 - 辅助空间: O(N) 或 O(n*k)
因为在 SortedMerge() 中使用了递归并合并最后 2 个大小为 N/2 的链表,所以将进行 N 次递归调用。
请参阅有关 Merge K 排序链表的完整文章 |设置 1 了解更多详情!