图解算法——合并两个有序链表

1. 题目描述

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {

    }
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2.示例

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

3. 题目要求:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

4. 题目解析

由示例2我们知道,当两个链表都为空时,返回空;当有一个为空时,直接返回另一个非空链表。这两个示例告诉了我们的临界情况。

一般情况就是示例1所示。

我们可以设置一个返回节点值ListNode res, 和一个当前节点值curNode;然后令res = curNode,在整个过程中,我们只使用curNode,res是作为返回值使用,因为要保持一个指向链表节点的节点指针。

思路是:先随意new一个值,使得curNode不为空。然后从 l1 链表和 l2 链表中头部开始,各挑出一个节点,比较大小,谁小,就让curNode的next指向谁,然后小的链表的指针指向该小节点的next位置,最后更新curNode节点使其指向curNode.next。进行下一次比较,直至 l1 和 l2 有不为空的情况。

当跳出循环时,说明 l1 和 l2 肯定至少有一个为空。谁为空,那就让curNode.next直接指向另一个非空的节点。

最后返回我们的返回节点res.next。有人会问不应该是res 嘛?怎么变成res.next 了?

仔细回想一下,我们一开始为了不让curNode 不为空,我们随机设置了一个值。而该值是没有意义的,真正来自l1 和 l2 的值是从 res.next 才开始的。

代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
     //临界判断
        if(l1==null && l2==null){
            return null;
        }
        if(l1 == null){
            return l2;
        }
        if(l2 == null){
            return l1;
        }
        
        ListNode curNode = new ListNode(-1);
        ListNode res = curNode;
        while(l1!=null && l2!=null){
            if(l1.val <= l2.val){
                curNode.next = l1;
                l1 = l1.next;
            }else{
                curNode.next = l2;
                l2 = l2.next;
            }
            curNode = curNode.next;
        }
        if(l1==null){
            curNode.next = l2;
        }
        if(l2==null){
            curNode.next = l1;
        }
        return res.next;
    }
}

5、附录

在这里我提交了两次,很幸运都直接通过了,哈哈哈。

第一次就直接获得了如下战绩,但是我想把开头的临界判断给去掉试试效果,没想到执行用时也没增加多少,但是从击败人数上看,明显的是思路不太完整。所以,不要小看这些临界条件,有时候会帮你省很多时间。

下图:加上临界判断:

 下图:去掉临界判断:

Over...............

原文地址:https://www.cnblogs.com/gjmhome/p/15004606.html