【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;
    }
}
相关推荐
2301_780789667 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
m0_639906948 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
学长毕设8 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn9 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川9 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵9 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David9 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1009 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin10 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质11 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring