(leetcode)力扣100 27合并两个有序链表(迭代/递归)

题目

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

数据范围

两个链表的节点数目范围是 0, 50

-100 <= Node.val <= 100

l1 和 l2 均按 非递减顺序 排列

测试用例

示例1

java 复制代码
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例2

java 复制代码
输入:l1 = [], l2 = []
输出:[]

示例3

java 复制代码
输入:l1 = [], l2 = [0]
输出:[0]

题解1 (迭代,时间O(N+M),空间O1)

java 复制代码
/**
 * 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 list1, ListNode list2) {
        ListNode res=new ListNode(-1);
        ListNode pre=res;

        while(list1!=null&&list2!=null){
            if(list1.val<=list2.val){
                pre.next=list1;
                list1=list1.next;
            }else{
                pre.next=list2;
                list2=list2.next;
            }
            pre=pre.next;
        }


        pre.next=list1 == null? list2:list1;

        return res.next;
    }
}

题解2(递归,时空O(N+M))

java 复制代码
/**
 * 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 list1, ListNode list2) {
        if(list1==null){
            return list2;
        }else if(list2==null){
            return list1;
        }else if(list1.val<=list2.val){
            list1.next=mergeTwoLists(list1.next,list2);
            return list1;
        }else{
            list2.next=mergeTwoLists(list1,list2.next);
            return list2;
        }
    }
}

思路

这道题没有特殊要求的话,舅姥姥老老实实用迭代吧,思路清晰,空间复杂度也低,不需要额外说明什么,就是设计了一个指针来记录头,另一个指针来遍历两个list。

递归的话代码较少,但思路麻烦,空间复杂度也高,但最好也掌握一下,万一被问到了呢?他的思路如下:

java 复制代码
我们可以把这个过程想象成**"层层外包"**的任务。

1. 核心思想:大任务化小任务
我们要合并两个链表,其实只需要做一件事:

比较两个链表的头节点,选出较小的那个作为合并后的头,然后把剩下的部分交给别人去处理。

2. 生活中的例子:排队领书
假设有两队学生(l1 和 l2),每个队都按身高从小到大排列。现在我们要把他们合并成一队。

比较: 你站在门口,看两队排头的人。发现 l1 的排头兵 A 比 l2 的排头兵 B 矮。

决定: 你让 A 站到新队伍的第一位。

外包(递归): 你对 A 说:"剩下的事情我不管了,你去连接后面的人吧。"

递归调用: A 于是回头看了一眼剩下的学生(l1 扣除 A 后的部分,以及完整的 l2 队),重复你刚才的操作。

3. 代码逻辑拆解
让我们对照你提供的 Java 代码来看:

出口(边界情况):

if (l1 == null) return l2; // 如果 l1 没学生了,剩下的全是 l2 的,直接接上去
if (l2 == null) return l1; // 反之亦然
这是递归的"底",没有它程序就会无限循环。

选择与连接:

if (l1.val < l2.val) {
    // l1 赢了,l1 成为当前的头
    // 关键:l1.next 等于【剩下的 l1】和【完整的 l2】合并的结果
    l1.next = mergeTwoLists(l1.next, l2); 
    return l1; // 返回已经接好的自己
}
相关推荐
信奥卷王2 小时前
[GESP202609 六级] 分树规划
算法
夏幻灵2 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表
徐小黑ACG3 小时前
Golang 基础05 结构体struct
开发语言·算法·golang
Navigator_Z4 小时前
LeetCode //C - 1286. Iterator for Combination
c语言·算法·leetcode
北极有牛4 小时前
cpp学习笔记--常量指针
java·开发语言·算法
GPU实战笔记4 小时前
云端 GPU 训练的账户余额提醒:它能说明什么,不能说明什么?
深度学习·算法·成本管理·gpu云计算·云端训练
浮链序5 小时前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
小O的算法实验室5 小时前
IEEE TMC,面向异构物联网的多目标量子行为拓扑优化算法
算法
圣保罗的大教堂5 小时前
leetcode 301. 删除无效的括号 困难
leetcode