力扣LeetCode第21题合并两个有序链表

本文详细介绍了如何合并两个已排序的链表,提供了两种方法:迭代和递归。迭代法通过建立虚拟头节点,逐个比较节点值进行拼接;递归法则通过不断比较节点值决定合并方向,直至链表为空。这两种方法都能有效地实现链表的有序合并。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

力扣第21题合并两个有序链表

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

在这里插入图片描述
思路:
1、首先建立一个两个节点指向同一个内存地址,之后让一个节点去移动去拼接节点
2、依次比较两个链表的值,较小的那个节点就要被移动的那个节点指向,最终返回不动的那个节点的next。
代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode preHead= new ListNode(0);
        ListNode prev= head;
        
        while(list1!=null&&list2!=null){
            if (list1.val <= list2.val) {
                prev.next = list1;
                prev= prev.next;
                list1 = list1.next;
            } else {
                prev.next = list2;
                prev= prev.next;
                list2 = list2.next;
            }
        }
        if(list1==null){
            prev.next=list2;
        }else{
            prev.next=list1;
        }
        return preHead.next;
    }
}

图示:
刚开始的初始节点对应的内存地址以及他们的关系
在这里插入图片描述
第一次循环结果 :第一次循环执行了

//由于实际操作的是内存地址,prev的内存是0x00000000,因为list1的值等于list2,prev的下一个节点是list1,
//这行代码导致了0x00000000指向了list1的第一个节点0x00000001,最终返回的链表现在是preHead->0x00000000->0x00000001
prev.next = list1;
//那么这个就导致了prev的内存地址指向了list1的第一个节点 0x00000001
prev = prev.next;
//那么此时list1节点到了链表的第二个节点位置0x00000001
list1 = list1.next;

在这里插入图片描述

第二次循环结果:执行了

//刚刚的prev指向内存0x00000001,现在执行这行语句prev的下一个节点内存地址就是list2,那么0x00000001连接到了0x00000004,
//整个返回的链表变成了preHead->0x00000000->0x00000001->0x00000004
prev.next = list2;
//prev此时指向0x00000004
prev= prev.next;
//list2往下移动,此时list2地址为0x00000005
list2 = list2.next;

在这里插入图片描述
第三次循环结果:执行了

//此时list1的值比较小,那么prev的下一个节点就是list1的内存地址,
//此时最终返回的链表是preHead->0x00000000->0x00000001->0x00000004->0x00000002
prev.next = list1;
//那么这个就导致了prev的内存地址指向  0x00000002(prev始终指向最终返回链表的末尾,因为是它需要去移动拼接)
prev = prev.next;
//那么此时list1节点到了链表的第三个节点位置0x00000003
list1 = list1.next;

在这里插入图片描述
那么往后按照此流程以此类推:最终的结果:
最终返回preHead.next那么就是preHead指向的链表
在这里插入图片描述
这个题目还有一种解法,那就是递归,递归不用创建新的节点,它就是直接将两个链表重新让节点断开连接上正确顺序的节点,最终返回。
代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    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;
        }
    }
}

如果l1比l2当前值小,然后l1的下一个节点与l2当前节点比较,l2比较小,那么此时l1.next就得指向l2的当前节点,然后l2的下一个节点与l1比较,以此类推下去,最终l1和l2会按照顺序连接起来。

算法专题:力扣LeetCode算法专题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值