023 合并K个升序链表-困难

题目:

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

解题思路

复习递归算法,掌握自底向上和自上向下的递归方法。

  • 最朴素的算法,顺次两两合并,详见解法1。递归算法,自底向上的两两合并。每个链表遍历一遍,所示时间复杂度O(n*k),空间复杂度O(1)。

  • 分治算法,类似归并排序,详见解法2。

// date 2023/10/17
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
// 解法1
// 最朴素的顺序两两合并
func mergeKLists(lists []*ListNode) *ListNode {
    if len(lists) == 0 {
        return nil
    }
    if len(lists) == 1 {
        return lists[0]
    }
    k := len(lists)
    l1, l2 := mergeKLists(lists[:k-1]), lists[k-1]
    dumy := &ListNode{}
    pre := dumy
    for l1 != nil && l2 != nil {
        if l1.Val < l2.Val {
            pre.Next = l1
            l1 = l1.Next
        } else {
            pre.Next = l2
            l2 = l2.Next
        }
        pre = pre.Next
    }
    if l1 != nil {
        pre.Next = l1
    }
    if l2 != nil {
        pre.Next = l2
    }
    return dumy.Next
}

// 解法2
// 分治思想,归并排序思想的合并
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func mergeKLists(lists []*ListNode) *ListNode {
    
    var merge func(lists []*ListNode, left, right int) *ListNode
    merge = func(lists []*ListNode, left, right int) *ListNode {
        if left == right {
            return lists[left]
        }
        if left > right {
            return nil
        }
        mid := left + (right- left)/2
        return mergeTwoList(merge(lists, left, mid), merge(lists, mid+1, right))
    }

    return merge(lists, 0, len(lists)-1)
}

func mergeTwoList(l1, l2 *ListNode) *ListNode {
    if l1 == nil {
        return l2
    }
    if l2 == nil {
        return l1
    }
    dummy := &ListNode{}
    cur := dummy
    for 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
    }
    if l1 != nil {
        cur.Next = l1
    }
    if l2 != nil {
        cur.Next = l2
    }
    return dummy.Next
}

最后更新于