合并K个排序链表
题目描述:
解题思路:
- 第一种:这个方法比较暴力,思路也很简单。就是把全部的链表都合成一个链表,然后对这一个链表进行排序,这样就把问题大大简化了。我们用
p
来存放结合后的链表,通过for
和while
循环将lists
的元素一个一个放入p
中。然后排序,并放入新的链表中返回。 - 时间复杂度:O(NlogN)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
p = []
_lis = head = ListNode(0)
for i in lists:
while i:
p.append(i.val)
i = i.next
for j in sorted(p):
_lis.next = ListNode(j)
_lis = _lis.next
return head.next
- 第二种:下面这个方法的思路挺不错的。用的是优先级队列的解法,其中用到了
heapq
模块,也就是堆队列的算法。这里用了一个大小为K的最小堆,通过用优先队列和自定义的降序来实现。先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中,这里heapq.heappop(p)
是取出堆中最小元素,所以我们依次将最小元素从堆中取出,然后放入新链表,最后返回。 - 时间复杂度:O(Nlogk)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
import heapq
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
p = []
_node = ListNode(0)
a = _node
for i in range(len(lists)):
if lists[i]:
heapq.heappush(p, (lists[i].val, i))
while p:
_, index = heapq.heappop(p)
head = lists[index]
a.next = head
a = a.next
if head.next:
heapq.heappush(p, (head.next.val, index))
lists[index] = head.next
head.next = None
return _node.next
或者这样的写法也行,和上面的区别就是入堆的方法用的不一样,这里用到了enumerate
函数来入堆。
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
q, curs = [], [] # curs存K个链表滑动的头指针
for i, n in enumerate(lists):
if n is not None:
heapq.heappush(q, (n.val, i))
curs.append(n)
_node = ListNode(0)
a = _node
while q:
val, index = heapq.heappop(q)
a.next = lists[index]
a = a.next
lists[index] = lists[index].next
if lists[index] is not None:
heapq.heappush(q, (lists[index].val, index))
return _node.next
- 第三种:分治法。这个方法将利用归并和排序的思想,利用递归方法和分治法将链表数组一直划分,变成越来越小的半链表数组,然后再对半链表数组进行排序,最后再通过递归的步骤将排好序的半链表数组合,合并成为越来越大的有序链表。简单来说就是一直在不停的对半划分,最后再结合在一起。
- 时间复杂度:O(Nlogk)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if len(lists) == 0:
return None
return self.__merge_k_lists(lists, 0, len(lists) - 1)
def __merge_k_lists(self, lists, left, right):
if left >= right:
return lists[left]
mid = left + (right - left) // 2
lino1 = self.__merge_k_lists(lists, left, mid)
lino2 = self.__merge_k_lists(lists, mid + 1, right)
return self.__merge_two_sorted_list_node(lino1, lino2)
def __merge_two_sorted_list_node(self, list1, list2):
if list1 is None:
return list2
if list2 is None:
return list1
if list1.val < list2.val:
list1.next = self.__merge_two_sorted_list_node(list1.next, list2)
return list1
else:
list2.next = self.__merge_two_sorted_list_node(list1, list2.next)
return list2