Merge Two Sorted Lists
https://leetcode.com/problems/merge-two-sorted-lists/
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode { dummy := &ListNode{} p := dummy p1 := list1 p2 := list2 for p1 != nil && p2 != nil { if p1.Val < p2.Val { p.Next = p1 p1 = p1.Next p = p.Next } else { p.Next = p2 p2 = p2.Next p = p.Next } } for p1 != nil { p.Next = p1 p1 = p1.Next p = p.Next } for p2 != nil { p.Next = p2 p2 = p2.Next p = p.Next } return dummy.Next }
优化解法
最后去合并剩余的 list1 / list2 时,不需要逐节点合并,只需要让 p.Next 指向最终剩余的 list 即可(其他节点已经「组成好一个有序链表」了)
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode { dummy := &ListNode{} p := dummy p1 := list1 p2 := list2 for p1 != nil && p2 != nil { if p1.Val < p2.Val { p.Next = p1 p1 = p1.Next p = p.Next } else { p.Next = p2 p2 = p2.Next p = p.Next } } if p1 != nil { p.Next = p1 } if p2 != nil { p.Next = p2 } return dummy.Next }
Partition List
https://leetcode.com/problems/partition-list/
题意:看上去返回的是一个链表,实际上是返回了两个链表连起来的。。
相当于生成两个新的链表,一个链表的所有值都 < x,另一个都 >=x ,再将这两个链表合到一起
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func partition(head *ListNode, x int) *ListNode { dummy1 := &ListNode{} dummy2 := &ListNode{} p1 := dummy1 p2 := dummy2 for p := head; p != nil; p = p.Next { if p.Val < x { p1.Next = p p1 = p1.Next } else { p2.Next = p p2 = p2.Next } } p1.Next = dummy2.Next p2.Next = nil return dummy1.Next }
Merge k Sorted Lists
https://leetcode.com/problems/merge-k-sorted-lists/
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func mergeKLists(lists []*ListNode) *ListNode { dummy := &ListNode{} p := dummy for { hasAny := false mi := -1 mv := 1000000 mp := (*ListNode)(nil) for i, h := range lists { if h == nil { continue } hasAny = true if h.Val < mv { mi = i mv = h.Val mp = h } } if !hasAny { break } p.Next = mp p = p.Next lists[mi] = lists[mi].Next } return dummy.Next }
上述代码时间复杂度为 O(lists.length * max(lists[i].length))
,即 O(NM)
考虑条件
0 <= lists[i].length <= 500
k == lists.length
,0 <= k <= 10^4
最大为 5 * 10^6 可以通过 OJ
优化方案
将所有优化方案
将所有 list 的头节点加入堆中,时间复杂度降为 O(sum(lists[i].length) * log(lists.length))
,即 O(NlogK)
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func mergeKLists(lists []*ListNode) *ListNode { dummy := &ListNode{} p := dummy pq := &NodeHeap{} for _, l := range lists { if l != nil { heap.Push(pq, l) } } for pq.Len() != 0 { v := heap.Pop(pq).(*ListNode) p.Next = v p = p.Next if v.Next != nil { heap.Push(pq, v.Next) } } return dummy.Next } type NodeHeap []*ListNode func (h NodeHeap) Len() int { return len(h) } func (h NodeHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h NodeHeap) Less(i, j int) bool { return h[i].Val < h[j].Val } func (h *NodeHeap) Push(x any) { *h = append(*h, x.(*ListNode)) } func (h *NodeHeap) Pop() any { n := len(*h) v := (*h)[n-1] *h = (*h)[:n-1] return v }