合併兩個或多個有序連結串列
阿新 • • 發佈:2022-03-18
合併兩個有序連結串列:
法一:迭代
package main func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode { dummyHead := &ListNode{} cursor := dummyHead for list1 != nil && list2 != nil { if list1.Val < list2.Val { cursor.Next = list1 list1 = list1.Next } else { cursor.Next = list2 list2 = list2.Next } cursor = cursor.Next } if list1 == nil { cursor.Next = list2 } else { cursor.Next = list1 } return dummyHead.Next }
法二:遞迴
package main func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode { if list1 == nil { return list2 } else if list2 == nil { return list1 } else if list1.Val < list2.Val { list1.Next = mergeTwoLists(list1.Next, list2) return list1 } else { list2.Next = mergeTwoLists(list1, list2.Next) return list2 } }
合併多個有序連結串列:
法一:分治法
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func mergeKLists(lists []*ListNode) *ListNode { var pre, cur *ListNode n := len(lists) for i := 0; i < n; i++ { if i == 0 { pre = lists[i] continue } cur = lists[i] pre = merge(pre, cur) } return pre } func merge(l1, l2 *ListNode) *ListNode { head := &ListNode{} cur := head for l1 != nil || l2 != nil { if l1 != nil && l2 != nil { if l1.Val < l2.Val { cur.Next = l1 l1 = l1.Next } else { cur.Next = l2 l2 = l2.Next } cur = cur.Next } else if l1 != nil { cur.Next = l1 break } else { cur.Next = l2 break } } return head.Next }
法二:小根堆
func mergeKLists(lists []*ListNode) *ListNode { k := len(lists) h := new(minHeap) for i := 0; i < k; i++ { if lists[i] != nil { heap.Push(h, lists[i]) } } dummyHead := new(ListNode) pre := dummyHead for h.Len() > 0 { tmp := heap.Pop(h).(*ListNode) if tmp.Next != nil { heap.Push(h, tmp.Next) } pre.Next = tmp pre = pre.Next } return dummyHead.Next } type minHeap []*ListNode func (h minHeap) Len() int { return len(h) } func (h minHeap) Less(i, j int) bool { return h[i].Val < h[j].Val } func (h minHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *minHeap) Push(x interface{}) { // Push and Pop use pointer receivers because they modify the slice's length, // not just its contents. *h = append(*h, x.(*ListNode)) } func (h *minHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x }