合并k个升序链表——分治法

182 阅读1分钟

image.png

顺序法合并

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func mergeKLists(lists []*ListNode) *ListNode {
    if len(lists) == 0 {
        return nil
    }
    head := lists[0]
    for i:=1; i<len(lists); i++{
        head = marge(head,lists[i])
    }
    return head
}

func marge(head1,head2 *ListNode) *ListNode{
    head := &ListNode{}
    temp := head
    for head1 != nil && head2 != nil {
        if head1.Val < head2.Val {
            temp.Next = head1
            head1 = head1.Next
        }else {
            temp.Next = head2
            head2 = head2.Next
        }
        temp = temp.Next
        if head1 == nil {
            temp.Next = head2
        }
        if head2 == nil {
            temp.Next = head1
        }
    }
    if head1 == nil {
        temp.Next = head2
    }
    if head2 == nil {
        temp.Next = head1
    }
    return head.Next
}

分治法合并

分治法核心两两相加,这个可以用递归实现

  1. merge函数将k个链表从中间分开,
  2. 需要参数 lists,l(起始位置),r(最终位置)
  3. (l+r)/2 得到中间位置mid
  4. 递归到最深处时,返回两个链表的和
  5. 然后两两合并返回最终值

image.png

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func mergeKLists(lists []*ListNode) *ListNode {
    return merge(lists,0,len(lists)-1)
}

func merge(lists []*ListNode, l,r int) *ListNode {
    if l == r {
        return lists[l]
    }
    if l > r {
        return nil
    }
    mid := (l + r) / 2
    return marge1(merge(lists,l,mid),merge(lists,mid+1,r))
}

func marge1(head1,head2 *ListNode) *ListNode{
    head := &ListNode{}
    temp := head
    for head1 != nil && head2 != nil {
        if head1.Val < head2.Val {
            temp.Next = head1
            head1 = head1.Next
        }else {
            temp.Next = head2
            head2 = head2.Next
        }
        temp = temp.Next
        if head1 == nil {
            temp.Next = head2
        }
        if head2 == nil {
            temp.Next = head1
        }
    }
    if head1 == nil {
        temp.Next = head2
    }
    if head2 == nil {
        temp.Next = head1
    }
    return head.Next
}