高频9. 合并两个有序链表 合并k个有序链表 去重 链表升序降序未知 及其变形题的各种解法 Java codetop

本文详细介绍了合并两个有序链表、去重合并、合并k个有序链表及其各种变形题的解法,包括递归、迭代、两两合并、分治、优先队列等策略。并探讨了链表顺序未知时如何生成指定顺序的链表。

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

题目描述

合并两个有序链表

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

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

各种解法

1. 递归合并两个链表

class Solution {
   
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
   
        // 终止条件是其中的一个链表是null
        if(list1 == null) return list2;
        if(list2 == null) return list1;
        // 把小的那个值加入到结果链表中
        if(list1.val < list2.val){
   
            list1.next = mergeTwoLists(list1.next, list2);
            return list1;
        }else{
   
            list2.next = mergeTwoLists(list1, list2.next);
            return list2;
        }
    }
}
解题思路
  • 递归解法,首先不要太关注细节,只要注重函数的功能就可以。该函数的功能就是能够合并两个有序链表。那么就把大问题转化为小问题。
  • 确定终止条件,一条链表为null,结果就是另一条链表
  • 然后对第一个节点进行处理,根据节点大小,以小的节点连接后面子问题的结果。

2. 迭代合并两个链表

class Solution {
   
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
   
        // 头结点之前的虚节点,为了回来能找到头结点
        ListNode hair = new ListNode(-1);
        ListNode pre = hair;
        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 hair.next;
    }
}
解题思路
  • 对于链表的题目,头结点很可能是不确定的,所以这时候用一个虚拟节点就可以起到很好的连接作用,最终肯定是hair.next
  • 每次把两条链表中较小值的节点连接到结果链表上面
  • 如果一条链表为空了,那么就可以直接把另一条链表的剩余部分接到结果链表上了。

变形题

1. 合并两个有序链表并且没有重复值,考虑去重

1.1 递归去重合并
解题思路
class Solution {
   
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
   
        //单个链表中有重复数字,直接跳到最后一个
        while(list1.next!=null&&list1.val==list1.next.val){
   
            list1=list1.next;
        }
        while(list2.next!=null&&list2.val==list2.next.val){
   
            list2=list2.next;
        }
        //list1与list2有相同元素
        if(list1.val==list2.val){
   
            if(list2.next!=null){
   
                list2=list2.next;
            }else{
   
                return list1;
            }
        }

        //以下就是官方递归解
        if(list1==null){
   
            return list2;
        }
        if(list2==null){
   
            return list1;
        }
        if(list1.val<lis
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值