(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; // 返回已经接好的自己
}
相关推荐
Brduino脑机接口技术答疑2 小时前
TDCA 算法在 SSVEP 场景中的 Padding 技术:原理、应用与工程实现
人工智能·算法·机器学习·数据分析·脑机接口
挖矿大亨2 小时前
C++中深拷贝与浅拷贝的原理
开发语言·c++·算法
发疯幼稚鬼2 小时前
图的存储与拓扑排序
数据结构·算法·排序算法·拓扑学
Bruce_kaizy2 小时前
c++图论——生成树之Kruskal&Prim算法
c++·算法·图论
LYFlied3 小时前
【每日算法】LeetCode 5. 最长回文子串(动态规划)
数据结构·算法·leetcode·职场和发展·动态规划
老赵聊算法、大模型备案3 小时前
《人工智能拟人化互动服务管理暂行办法(征求意见稿)》深度解读:AI“拟人”时代迎来首个专项监管框架
人工智能·算法·安全·aigc
雪花desu3 小时前
【Hot100-Java中等】/LeetCode 128. 最长连续序列:如何打破排序思维,实现 O(N) 复杂度?
数据结构·算法·排序算法
松涛和鸣3 小时前
41、Linux 网络编程并发模型总结(select / epoll / fork / pthread)
linux·服务器·网络·网络协议·tcp/ip·算法
鹿角片ljp3 小时前
力扣26.有序数组去重:HashSet vs 双指针法
java·算法