LeetCode 算法题库学习(23)

Letitia ·
更新时间:2024-09-21
· 518 次阅读

合并K个排序链表 题目描述:

timu

解题思路: 第一种:这个方法比较暴力,思路也很简单。就是把全部的链表都合成一个链表,然后对这一个链表进行排序,这样就把问题大大简化了。我们用p来存放结合后的链表,通过forwhile循环将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

1

第二种:下面这个方法的思路挺不错的。用的是优先级队列的解法,其中用到了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

2

第三种:分治法。这个方法将利用归并和排序的思想,利用递归方法和分治法将链表数组一直划分,变成越来越小的半链表数组,然后再对半链表数组进行排序,最后再通过递归的步骤将排好序的半链表数组合,合并成为越来越大的有序链表。简单来说就是一直在不停的对半划分,最后再结合在一起。 时间复杂度: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

3


作者:Justpcode



题库 leetcode 学习 算法

需要 登录 后方可回复, 如果你还没有账号请 注册新账号