leetcode21 合并两个有序链表——链表插入

一、题目描述

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists

二、解题思路与代码

题目中给的示例是l1和l2,为避免混淆,将其改为fir和sec。本题思路为使用两个指针同时遍历两个单链表,若sec的当前节点值小于fir的当前节点值,则将其插入到fir中,否则fir往后走。具体涉及涉及单链表节点的拆分与插入。

单链表节点拆分需要做如下两件事:
1. 断开当前节点与下一节点;
2. 前一节点的后继指向当前节点的后继。
假设当前节点为node,则可表示为如下代码:

node.next = node.next.next; // 要保证node.next != null,在实际应用中需注意

假设新插入的节点为newNode,插入单链表preNode节点后,插入新节点需要做如下两件事:
1. 让newNode的后继指向preNode的后继;
2. 让preNode的后继指向newNode。
即:

newNode.next = preNode.next; // 让新节点与插入位置节点的下一个节点相连
preNode.next = newNode; // 让插入位置节点与新节点相连
/**
 * 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) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        ListNode fir = new ListNode();
        ListNode sec = new ListNode();
        ListNode pre = fir;
        fir.next = l1;
        sec.next = l2;
        
      
        while (fir.next != null && sec.next != null) {
            if (fir.next.val <= sec.next.val) {
                fir = fir.next;
                continue;
            }
            
           	ListNode newNode = sec.next;
           	
           	// 拆分节点
            sec.next = sec.next.next;
            
			//插入新节点
            newNode.next = fir.next;
            fir.next = newNode;
            
            fir = fir.next;
        }
        if (fir.next == null) {
            fir.next = sec.next;
        } 
        return pre.next;
    }
}

三、注意事项

当fir、sec走到末尾的时候应该怎么处理,需要分别考虑(留个悬念)。