LeeCode_21. 合并两个有序链表(新链表+递归)

一、介绍

1.题目描述

题目链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/

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

2.测试样例

[1,2,4]
[1,3,4]
# [1,1,2,3,4,4]

[]
[]
# []

[]
[0]
# [0]

二、题解

  • 当字符串长度为奇数,必定不匹配
  • 将左括号推入,右括号进入时,若匹配则弹出,否则一定不匹配

1、新建链表、迭代合并🟡

新建一个链表p,新建q=p,q作为加入元素的指针。

由于链表已经升序,直接遍历两个原始链表,不断将当前最小值加入新链表,指针后移,就可以得到解

1、当 l1 指向的数值< l2指向的数值,l1赋给 q,l1指针后移;反之l2赋给 q,l2指针后移。

2、p后移

3、重复步骤12,直至某个链表为空

4、将另一个非空链表直接加在最后

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *p=new ListNode(-1);
        ListNode *q=p;
        while(l1!=nullptr&&l2!=nullptr){
            // 数值小的链表赋给 q , 链表指针后移,q 后移
            if(l1->val<l2->val){
                q->next=l1;
                l1=l1->next;
            }
            else{
                q->next=l2;
                l2=l2->next;
            }
            q=q->next;
        }
        // 某个原链表为空后,将另一个的剩余内容加到末尾
        q->next=l1==nullptr?l2:l1;
        return p->next;
    }
};

2、递归🟡

该题的递归公式如下:

  • 若其中一个链表为空,则返回另一个链表 
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1==nullptr) return l2;
        if(l2==nullptr) return l1;
        if(l1->val<l2->val) {
            l1->next=mergeTwoLists(l1->next,l2);
            return l1;
        }
        else{ 
            l2->next=mergeTwoLists(l1,l2->next);
            return l2;
        }
    }
};

非常好的问题! 对于 **LeetCode 第 21 题:合并两个有序链表**,题目描述如下: > 将两个升序链表合并为一个新的 **升序** 链表新链表应通过拼接给定的两个链表的所有节点来组成,**不创建额外的节点**。 --- ### ✅ 所以答案是: > **不可以创建新的节点,也不可以创建新的链表。** > 你只能在两个原始链表的基础上,**通过修改指针(next)来完成合并**。 --- ### 🔍 举个例子: ```text 输入: l1 = 1 -> 2 -> 4 l2 = 1 -> 3 -> 4 输出: 合并后的链表1 -> 1 -> 2 -> 3 -> 4 -> 4 ``` 这个合并过程是通过逐个比较节点值的大小,然后**把较小节点的 next 指向下一个待比较的节点**,最终形成一个完整的升序链表。 --- ### ✅ 示例代码(递归法): ```java public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) { return l2; } if (l2 == null) { return l1; } if (l1.val < l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; } else { l2.next = mergeTwoLists(l1, l2.next); return l2; } } ``` 这个方法没有创建任何新节点,只是通过递归修改指针的方式完成了合并。 --- ### ✅ 迭代法也可以做到: ```java public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode dummy = new ListNode(0); // 辅助节点,不是新链表 ListNode curr = dummy; while (l1 != null && l2 != null) { if (l1.val < l2.val) { curr.next = l1; l1 = l1.next; } else { curr.next = l2; l2 = l2.next; } curr = curr.next; } curr.next = l1 != null ? l1 : l2; return dummy.next; // 返回原始链表合并后的头节点 } ``` 虽然这里用了 `dummy` 节点,但它只是一个辅助节点,**并不是新的链表结构**。最终返回的也是拼接后的原始节点组成的链表。 --- ### ✅ 总结 | 问题 | 回答 | |------|------| | 是否可以创建新节点? | ❌ 不可以 | | 是否可以创建新链表? | ❌ 不可以,只能通过修改指针进行拼接 | | 是否可以使用 dummy 节点? | ✅ 可以,它只是辅助节点,不参与最终链表结构 | | 最终返回的是什么? | 返回拼接后的头节点(l1 或 l2 的修改后版本) | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值