方法一:水平扫描法
将合并 k 个有序链表看为多个合并两个有序链表
func mergeKLists(lists []*ListNode) *ListNode {
head := &ListNode{}
node := head.Next
for _, item := range lists {
node = mergeTwoLists(node, item)
}
return node
}
func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
head := &ListNode{}
current := head
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
current.Next = list1
list1 = list1.Next
} else {
current.Next = list2
list2 = list2.Next
}
current = current.Next
}
if list1 != nil {
current.Next = list1
} else if list2 != nil {
current.Next = list2
}
//return current.Next
//注意返回值!
return head.Next
}
方法二:分治法
分治法在合并k个升序链表时通常比水平扫描方法更快。分治法通过递归地将k个链表分为两半,然后合并,这样减少了重复比较的次数,时间复杂度为O(Nlogk),其中N是所有链表中元素的总数,k是链表的数量。
相比之下,水平扫描方法每次合并两个链表,总共需要合并k-1次,时间复杂度为O(kN),在k较大时,性能较分治法差。因此,对于大量链表的合并问题,分治法更为高效。
func mergeKLists(lists []*ListNode) *ListNode {
if len(lists) < 1 {
return nil
}
//切两半
return mergeRangeLists(lists, 0, len(lists)-1)
}
func mergeRangeLists(lists []*ListNode, start, end int) *ListNode {
if start >= end {
return lists[start]
}
//这里起始应该是start,而不是0
//left := mergeRangeLists(lists, 0, (end-start)/2)
//right := mergeRangeLists(lists, (end-start)/2+1, end)
left := mergeRangeLists(lists, start, start+(end-start)/2)
right := mergeRangeLists(lists, start+(end-start)/2+1, end)
return mergeTwoLists(left, right)
}
func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
head := &ListNode{}
current := head
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
current.Next = list1
list1 = list1.Next
} else {
current.Next = list2
list2 = list2.Next
}
current = current.Next
}
if list1 != nil {
current.Next = list1
} else if list2 != nil {
current.Next = list2
}
//return current.Next
//注意返回值!
return head.Next
}