(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; // 返回已经接好的自己
}
相关推荐
祖力558 小时前
数据结构的基本概念与单向链表(链表数据类型构造、创建、头插、尾插、头删、尾删)
数据结构·链表
大明者省9 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_79811 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander25811 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记11 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI12 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型12 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光12 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院14 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡14 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构