【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;
    }
}
相关推荐
Sarvartha14 分钟前
final 关键字
java·开发语言
2601_9520477919 分钟前
单一策略深度教程:用轻易云把集成任务的报错实时推送到钉钉机器人
java·机器人·钉钉
yi01129 分钟前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
数据狐(Datafox)1 小时前
淘宝图片搜索 API 落地实战:基于以图搜货搭建跨境电商选品系统
java·大数据·微服务
Escalating_xu3 小时前
【C 语言】数据在内存中的存储:补码、大小端、整型陷阱与 IEEE 754 全解析
java·c语言·网络
灯澜忆梦3 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
禾小西3 小时前
Redis 数据结构:快速的 Redis 有哪些慢操作?
数据结构·数据库·redis
一个风轻云淡3 小时前
GCC 和 GDB命令简单解读
java·linux·前端