一道腾讯面试题,击败100%的用户,合并排序链表

338次阅读  |  发布于3年以前

题目

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:

输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 限制:

0 <= 链表长度 <= 1000

注意:本题与主站 21 题相同:https://leetcode-cn.com/problems/merge-two-sorted-lists/

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字思路

图解思路

上述图片中的文字:

动画

代码

Java

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode();
        ListNode cur = dummy;
        while(l1 != null && l2 != null){
            if(l1.val <= l2.val){
                cur.next = l1;
                l1 = l1.next;
            }else{
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        cur.next = l1 != null ? l1 : l2;
        return dummy.next;
    }
}

JS

const mergeTwoLists = (l1, l2) => {
    // 定义一个虚拟节点,最后返回虚拟节点的下一个节点
    const res = new ListNode(0);
    // 定义p指向虚拟节点
    let p = res;
    // 定义p1,p2分别指向两个链表头部
    let [p1, p2] = [l1, l2];
    // 当p1, p2都有值的时候
    while (p1 && p2) {
        // 如果p1指向的值小,则p指向p1的值
        // p1右移
        // 否则p指向p2的值,p2右移
        if (p1.val < p2.val) {
            p.next = p1;
            p1 = p1.next;
        } else {
            p.next = p2;
            p2 = p2.next;
        }
        // 记得p也要右移
        p = p.next;
    }
    // 到最后退出循环了,p1,p2肯定有且只有一个是null
    // 那么另一个不是null的还没有连接到p上
    // 把p再连接到不是null的那个
    p.next = p1 ? p1 : p2;
    // 返回虚拟节点的下一个节点
    return res.next;
};

Python

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        res = ListNode(-1)
        p = res
        while l1 and l2:    
            if l1.val < l2.val:
                p.next = l1
                l1 = l1.next
            else:
                p.next = l2
                l2 = l2.next
            p = p.next
        p.next = l1 if l1 is not None else l2
        return res.next

C++

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* pHead = new ListNode(0);
        ListNode* pNode = pHead;
        while (l1 != NULL && l2 != NULL) {
            if (l1->val < l2->val) {
                pNode->next = l1;
                l1 = l1->next;
            }
            else {
                pNode->next = l2;
                l2 = l2->next;
            }
            pNode = pNode->next;
        }
        // 比较妙的一点在这里,就像归并排序一样最后要把没合并完的直接放进来,这里就不用遍历了,直接把节点挂上来就行
        if (l1)
            pNode->next = l1;
        else if (l2)
            pNode->next = l2;
        return pHead->next;
    }
};

Go


/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
    if l1==nil {return l2}
    if l2==nil {return l1}

    var n *ListNode
    if l1.Val<l2.Val {
        n = l1
        n.Next = mergeTwoLists(l1.Next,l2)
    } else {
        n = l2
        n.Next = mergeTwoLists(l1,l2.Next)
    }

    return n
}

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8