需求
合并 k
个已排序的链表并将其作为一个已排序的链表返回
[{1,2,3},{4,5,6,7}] // 入参
{1,2,3,4,5,6,7} // 返回
分治+递归
- 用二分法把列表进行中间拆分
- 融合每个小列表中的链表,反向
func mergeKLists( lists []*ListNode ) *ListNode {
if lists == nil{
return nil
}else if len(lists) == 1 {
return lists[0] //
}
mid := len(lists)/2
left,right := mergeKLists(lists[:mid]),mergeKLists(lists[mid:])
return merge(left,right) // 两个有序链表合并
}
func merge(t1, t2 *ListNode) *ListNode {
dummy := &ListNode{}
cur := dummy
for t1 != nil && t2 != nil {
if t1.Val < t2.Val {
cur.Next = t1
t1 = t1.Next
}else {
cur.Next = t2
t2 = t2.Next
}
cur = cur.Next
}
if t1 != nil {
cur.Next = t1
}
if t2 != nil {
cur.Next = t2
}
return dummy.Next
}
最小堆
思路 用一个大小为K的最小堆,优先队列+自定义降序
- 优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头元素最小
- 先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
import heapq
dump= ListNode(0)
p = dump
head = []
for i in range(len(lists)):
if lists[i] :
heapq.heappush(head, (lists[i].val, i))
lists[i] = lists[i].next
while head:
val, idx = heapq.heappop(head)
p.next = ListNode(val)
p = p.next
if lists[idx]:
heapq.heappush(head, (lists[idx].val, idx))
lists[idx] = lists[idx].next
return dump.next