剑指 Offer 25. 合并两个排序的链表

博客围绕输入两个递增排序链表,将其合并成新的递增排序链表展开。介绍了解题思路,定义伪头节点和辅助指针,采用尾插法合并链表。还总结了Java中链表的相关知识,强调链表节点是引用类型,以及辅助指针的意义。

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

题目

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
限制:
0 <= 链表长度 <= 1000

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
思路
解题思路:
  1. 定义一个节点head,作为合并后得到的链表的伪头节点(不存储实际数据)。=>最终return head.next;
    再定义一个指针temp,作为辅助指针,指向链表head的尾节点(因为链表head采用的是 尾插法)。
    对于链表 L1、L2,不设置辅助指针,可以之间将L1、L2两个指针,边遍历边后移。
  2. 当L1!= null && L2!=null时,比较L1和L2的val的大小,取其中较小的节点,加入到head所在的链表中(尾插法);
  3. 直到L1和L2所在的链表中,出现至少一个==null,即L1或L2所在链表,有至少一个链表已经完成遍历时,退出2、的循环,将没有遍历完的链表中的所有剩余节点,加入到head所在的链表中(尾插法);
  4. 需要注意的是:
    =>对于合并的链表head,对其中进行加入节点的操作的时候,采用的是:尾插法。
    =>在进行尾插法的操作时,是直接让head所在链表的temp节点的next域指向 要插入的节点,随后更新temp指针,使它指向新的尾节点。
实现
class Solution {
    
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        //不用定义两个辅助指针,用于遍历l1、l2两个链表。因为l1、l2,实际上就可以作为对应的遍历指针。
        ListNode head = new ListNode(0);//头节点(不存数据的那种)
        ListNode temp = head;//尾节点(辅助插入节点--尾插法)

        //l1、l2不空的情况下
        while(l1!=null && l2!=null){
            //谁的节点的val小,将谁的先插入到head对应的链表中去
            if(l1.val <= l2.val){
                temp.next = l1;
                temp = temp.next;//指向当前的尾节点
                l1 = l1.next; //更新l1
            }else{
                temp.next = l2;
                temp = temp.next;//指向当前的尾节点
                l2 = l2.next;//更新l2
            }
        }
        //l1、l2所在的链表中,至少有一条已经遍历完的情况下,
        //先找到哪个链表遍历完了(分为3中情况,其实处理起来只有两种需要另外进行处理)
        if(l1 == null && l2!= null){
            //l1空,l2不空=>将l2中的剩余元素,加入到head所在链表中去
            temp.next = l2;
        } else if(l1 != null && l2 == null){
            //l1不空,l2空=>将l1中的剩余元素,加入到head所在链表中去
            temp.next = l1;
        /*}else{
            //l1、l2都空了
            temp.next = null;//其实,感觉不要也可以,因为temp最终一定是指向l1、l2所在链表中的某一个链表的尾节点*/
        }
            return head.next;
    }

}
总结

刚看到这道题的时候,很快就有了思路,但是处理起来却花了很长的时间,主要是因为:对于Java中的链表的理解还是不够清晰。下面进行一个小的 关于Java中链表的理解 的一个总结:

  1. 链表中的节点的类型,是一个自定义类,所以节点属于引用类型。与前边JavaSE阶段学到的其他的引用类型的变量一样,拥有相同的性质。
  2. "ListNode tail = null;"具有的实际意义就是:在栈中定义了一个ListNode类型的变量,该变量目前没有指向堆空间中的任何区域(没有造一个对象,使它指向这个新对象;也没有指向一个之前已经造好的对象)。
    "tail = head; "所起到的作用:让栈中的 tail变量,指向栈空间中的head指向的堆空间中的区域。在进行下一个这样的赋值(将tail指向堆空间中的其他区域)之前,由于类属于引用类型,对tail进行的所有操作,实际上也是对head进行的所有操作,也就是对它们共同指向的堆空间中的一个区域中的数据进行的操作。
  3. 注意:
    =>这是引用类型的真正内涵,也是 链表中定义辅助变量(辅助指针)的意义所在,不要迷!!!!!!
    =>很重要的一点,在Java中,链表的节点,对应的是一个封装好的类 的对象。

行百里者半九十!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值