【LeetCodehot100】T23:合并k个升序链表

T23:合并k个升序链表

题目要求:

k 个已经排好序的链表

例如:

list1: 1 → 4 → 5

list2: 1 → 3 → 4

list3: 2 → 6

要求:

把它们合并成一个新的有序链表

最终结果:

1 → 1 → 2 → 3 → 4 → 4 → 5 → 6

题目核心

如何把多个有序链表合并成一个有序链表?

核心思路(分治 / 归并)

像归并排序一样:

k个链表

分成两半

分别合并

再合并结果

分治函数,合并链表代码实现

分治函数

java 复制代码
private ListNode merge(ListNode[] lists, int left, int right){
    if(left == right){
        return lists[left];
    }

    int mid = (left + right) / 2;

    ListNode l1 = merge(lists, left, mid);
    ListNode l2 = merge(lists, mid + 1, right);

    return mergeTwoLists(l1, l2);
}

逻辑:

递归拆分

直到只剩一个链表

再开始合并

合并两个链表

java 复制代码
private ListNode mergeTwoLists(ListNode l1, ListNode l2){

    ListNode dummy = new ListNode(0);
    ListNode cur = dummy;

    while(l1 != null && l2 != null){

        if(l1.val < l2.val){
            cur.next = l1;
            l1 = l1.next;
        }else{
            cur.next = l2;
            l2 = l2.next;
        }

        cur = cur.next;
    }

    if(l1 != null) cur.next = l1;
    if(l2 != null) cur.next = l2;

    return dummy.next;
}

代码实现

java 复制代码
class Solution {

    // 主函数:合并 k 个有序链表
    public ListNode mergeKLists(ListNode[] lists) {

        // 边界情况:如果数组为空,直接返回 null
        if (lists == null || lists.length == 0) {
            return null;
        }

        // 调用分治函数
        return merge(lists, 0, lists.length - 1);
    }


    // 分治函数:负责把多个链表不断拆分并合并
    private ListNode merge(ListNode[] lists, int left, int right) {

        // 如果只剩一个链表,直接返回
        if (left == right) {
            return lists[left];
        }

        // 计算中间位置
        int mid = (left + right) / 2;

        // 递归合并左半部分
        ListNode l1 = merge(lists, left, mid);

        // 递归合并右半部分
        ListNode l2 = merge(lists, mid + 1, right);

        // 最后把两个已经排好序的链表合并
        return mergeTwoLists(l1, l2);
    }


    // 合并两个有序链表(经典模板)
    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {

        // 创建虚拟头节点(方便操作)
        ListNode dummy = new ListNode(0);

        // cur 指针用于构建新链表
        ListNode cur = dummy;

        // 只要两个链表都没遍历完
        while (l1 != null && l2 != null) {

            // 谁小就接谁
            if (l1.val < l2.val) {

                cur.next = l1;   // 接入 l1 节点
                l1 = l1.next;    // l1 指针后移

            } else {

                cur.next = l2;   // 接入 l2 节点
                l2 = l2.next;    // l2 指针后移

            }

            // cur 指针前进
            cur = cur.next;
        }

        // 如果 l1 还有剩余节点
        if (l1 != null) {
            cur.next = l1;
        }

        // 如果 l2 还有剩余节点
        if (l2 != null) {
            cur.next = l2;
        }

        // 返回合并后的链表头节点
        return dummy.next;
    }
}
相关推荐
流水武qin2 小时前
SpringAI多模态的基本使用
java·spring boot·spring·ai
共享家95272 小时前
Java入门(多态)
java·开发语言
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于Java的婚礼策划平台的设计与实现为例,包含答辩的问题和答案
java·开发语言
_饭团2 小时前
指针核心知识:5篇系统梳理3
c语言·数据结构·算法·leetcode·面试·学习方法·改行学it
吾诺2 小时前
Spring Boot--@PathVariable、@RequestParam、@RequestBody
java·spring boot·后端
星空露珠3 小时前
又双叒叕统计被炸死的lua脚本
开发语言·数据结构·算法·游戏·lua
luanma1509803 小时前
Spring 框架——@Retryable 注解与 @Recover 注解
java·前端·spring
阿Y加油吧3 小时前
力扣打卡——day01
java·算法·leetcode
码路飞3 小时前
Java 25 发了但更让我兴奋的是这个:Spring AI 让 Java 调大模型终于不用手写 HTTP 了
java·人工智能·spring