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

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

在这里插入图片描述

一、递归

思路:

  1. 如果有一个链表为空,返回另一个链表
  2. 如果 l1 结点小于 l2,下一个结点就是 l1,应该 return l1。在 return 之前,指定 l1 的下一个结点为 l1.next 和 l2 两个链表合并后的头结点
  3. 如果 l1 结点大于 l2,下一个结点就是 l2,应该 return l2。在 return 之前,指定 l2 的下一个结点为 l1 和 l2.next 两个链表合并后的头结点
/**
 * 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 || l2 == null)
            return l1 == null ? l2 : l1;

        if(l1.val <= l2.val){
            l1.next = mergeTwoLists(l1.next,l2);
            return l1;
        }else{
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}
  • 时间复杂度:O(m+n),m 和 n 分别为两链表长度
  • 空间复杂度:O(m+n)

二、伪头节点

根据题目描述,链表 l1,l2 是递增的,因此容易想到使用双指针 l1 和 l2 遍历两链表,根据 l1.val 和 l2.val 的大小关系确定结点添加顺序,两结点指针交替前进,直至遍历完毕

引入伪头结点:由于初始状态合并链表中无结点,因此循环第一轮时无法将结点添加到合并链表中。解决方案:初始化一个辅助结点 dum 作为合并链表的伪头结点,将各结点添加至 dum 之后
在这里插入图片描述
算法流程:

  1. 初始化:伪头结点 dum,结点 cur 指向 dum
  2. 循环合并:当 l1 或 l2 为空时跳出
    1. 当 l1.val < l2.val 时:cur 的后继节点指定为 l1,并且 l1 向前走一步
    2. 当 l1.val ≥ l2.val 时:cur 的后继节点指定为 l2,并且 l2 向前走一步
    3. 结点 cur 向前走一步,即 cur = cur.next
  3. 合并剩余尾部:跳出时有两种情况,即 l1 为空或 l2 为空
    1. 若 l1 ≠ null:将 l1 添加至结点 cur 之后
    2. 否则:将 l2 添加至结点 cur 之后
  4. 返回值:合并链表在伪头结点 dum 之后,因此返回 dum.next 即可
/**
 * 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){
		ListNode dum = new ListNode(0);
		ListNode cur = dum;
		while(l1 != null && l2 != null){
			if(l1.val < l2.val){
				cur.next = l1;
				l1 = l1.next;
			}else{
				cur.next = l2;
				l2 = l2.next;
			}
		}
		if(l1 == null || l2 == null)
			l1 == null ? cur.next = l2 : cur.next = l1;
		return cur.next;
	}
}
  • 时间复杂度 O(m + n)
  • 空间复杂度 O(1):结点引用 dum,cur 使用常数大小的额外空间

总结

一开始没有想到使用伪头结点,而是借助辅助结点将 l2 中的结点插入到 l1,通过了测试代码,但是提交失败。因为当 l2 中的结点小于 l1 的头结点,那么就不能直接返回 l1 了,需要加很多判断,就很繁琐。伪头结点是很容易理解的,但递归我是一点思路都没有,递归 yyds
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值