牛客刷题-go-链表合并、归并排序

103 阅读1分钟

T1. 合并两个有序链表

改进下:
func Merge(pHead1 *ListNode, pHead2 *ListNode) *ListNode {
    newHead := &ListNode{}
    cur := newHead
    for pHead1 != nil && pHead2 != nil {
        if pHead1.Val < pHead2.Val {
            cur.Next = pHead1
            pHead1 = pHead1.Next
        } else { //if else 还是 if continue好用???
            cur.Next = pHead2
            pHead2 = pHead2.Next
        }
        cur = cur.Next
    }
    if pHead1 == nil {
        cur.Next = pHead2
    }
    if pHead2 == nil {
        cur.Next = pHead1
    }
    return newHead.Next
}
一个问题:

if else 还是 if continue好用?

旧版:
func Merge(pHead1 *ListNode, pHead2 *ListNode) *ListNode {
    if pHead1 == nil && pHead2 == nil {
        return pHead1
    }
    newHead := &ListNode{}
    cur := newHead
    for pHead1 != nil {
        if pHead2 == nil { //改进,if非必要勿放循环里,浪费
            cur.Next = pHead1
            return newHead.Next
        }
        if pHead1.Val < pHead2.Val {
            cur.Next = pHead1
            pHead1 = pHead1.Next
            //cur = cur.Next    放在后面
        } else {
            cur.Next = pHead2
            pHead2 = pHead2.Next
            //cur = cur.Next
        } /*else {   //不需要对pHead1 == pHead2 做判断!!!
            cur.Next = pHead1
            pHead1 = pHead1.Next
            cur = cur.Next
            cur.Next = pHead2
            pHead2 = pHead2.Next
            cur = cur.Next
        }*/
        cur = cur.Next
    }
    cur.Next = pHead2
    return newHead.Next

}

T2. 合并k个有序链表

法一:递归分治实现         法二:新链表和每个链表合并

举例说明复杂度:10个链表合并

法一链表最多遍历三次,至少两次,共24次,法二链表最多遍历9次,遍历次数依次减少,共54次

func mergeKLists(lists []*ListNode) *ListNode {
    if lists == nil {
        return nil
    }
    //start := 0
    //end := len(lists) - 1
    return divide(lists, 0, len(lists)-1)
}
func divide(lists []*ListNode, start, end int) *ListNode {
    if start == end {
        return lists[start]
    }
    if start > end {
        return nil
    }
    mid := (start + end) / 2
    left := divide(lists, start, mid)
    right := divide(lists, mid+1, end)
    return merge(left, right)
}
func merge(l1 *ListNode, l2 *ListNode) *ListNode {
    newl := &ListNode{}
    cur := newl
    for l1 != nil && l2 != nil {
        if l1.Val < l2.Val {
            cur.Next = l1
            l1 = l1.Next
            //cur = cur.Next
        } else {
            cur.Next = l2
            l2 = l2.Next
        }
        cur = cur.Next
    }
    if l1 == nil {
        cur.Next = l2
    }
    if l2 == nil {
        cur.Next = l1
    }
    return newl.Next
}

T3. 链表排序****

归并排序(divide()中的结束条件别忘写)

func sortInList(head *ListNode) *ListNode {
    if head == nil || head.Next == nil { // divede()结束条件别忘!!!
        return head
    }
    mid := &ListNode{-1, head}
    end := mid
    for end != nil && end.Next != nil {
        end = end.Next.Next
        mid = mid.Next
    }
    right := mid.Next
    mid.Next = nil
    l1 := sortInList(head)
    l2 := sortInList(right)
    return sort(l1, l2)
}

func sort(head1, head2 *ListNode) *ListNode {
    new1, new2 := head1, head2
    newHead := &ListNode{-1, nil}
    res := newHead
    for new1 != nil && new2 != nil {
        if new1.Val < new2.Val {
            newHead.Next = new1
            new1 = new1.Next
        } else {
            newHead.Next = new2
            new2 = new2.Next
        }
        newHead = newHead.Next
    }
    if new1 != nil {
        newHead.Next = new1
    }
    if new2 != nil {
        newHead.Next = new2
    }
    return res.Next
}