【LeetCode刷题记录】23. 合并 K 个升序链表

23 合并 K 个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]

输出:[1,1,2,3,4,4,5,6]

解释:链表数组如下:

1-\>4-\>5, 1-\>3-\>4, 2-\>6

将它们合并到一个有序链表中得到。

1->1->2->3->4->4->5->6

示例 2:

输入:lists = []

输出:[]

示例 3:

输入:lists = [[]]

输出:[]

提示:

k == lists.length
0 < = k < = 1 0 4 0 <= k <= 10^4 0<=k<=104

0 <= lists[i].length <= 500
− 1 0 4 < = l i s t s [ i ] [ j ] < = 1 0 4 -10^4 <= lists[i][j] <= 10^4 −104<=lists[i][j]<=104

lists[i] 按 升序 排列

lists[i].length 的总和不超过 1 0 4 10^4 104

思路

(1)有序合并:

先写一个合并两个有序链表的函数,在对K个有序链表进行顺序合并。

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* head = new ListNode;
        ListNode* p = head;
        while (list1 != nullptr && list2 != nullptr) {
            if (list1->val <= list2->val) {
                p->next = list1;
                list1 = list1->next;
            } else {
                p->next = list2;
                list2 = list2->next;
            }
            p = p->next;
        }
        p->next = list1 != nullptr ? list1 : list2;
        return head->next;
    }
};

(2)归并:

使用归并排序,每次两两合并两个有序链表即可

cpp 复制代码
ListNode* merge(vector<ListNode*>& lists, int l, int r) {
        if (l == r) {
            return lists[l];
        }
        if (l > r) {
            return nullptr;
        }
        int mid = (l + r) / 2;
        ListNode* start = merge(lists, l, mid);
        ListNode* end = merge(lists, mid + 1, r);
        ListNode* ans = mergeTwoLists(start, end);
        return ans;
    }

代码

法一:

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* head = new ListNode;
        ListNode* p = head;
        while (l1 != nullptr && l2 != nullptr) {
            if (l1->val <= l2->val) {
                p->next = l1;
                l1 = l1->next;
            } else {
                p->next = l2;
                l2 = l2->next;
            }
            p = p->next;
        }
        p->next = l1 ? l1 : l2;
        return head->next;
    }

    // 顺序合并
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        int n = lists.size();
        ListNode* ans = nullptr;
        for (int i = 0; i < n; i++) {
            ans = mergeTwoLists(ans, lists[i]);
        }
        return ans;
    }
};

法二:

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* head = new ListNode;
        ListNode* p = head;
        while (l1 != nullptr && l2 != nullptr) {
            if (l1->val <= l2->val) {
                p->next = l1;
                l1 = l1->next;
            } else {
                p->next = l2;
                l2 = l2->next;
            }
            p = p->next;
        }
        p->next = l1 ? l1 : l2;
        return head->next;
    }
    
    // 归并
    ListNode* merge(vector<ListNode*>& lists, int l, int r) {
        if (l == r) {
            return lists[l];
        }
        if (l > r) {
            return nullptr;
        }
        int mid = (l + r) / 2;
        ListNode* start = merge(lists, l, mid);
        ListNode* end = merge(lists, mid + 1, r);
        ListNode* ans = mergeTwoLists(start, end);
        return ans;
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* ans = merge(lists, 0, lists.size() - 1);
        return ans;
    }
};
相关推荐
leke200318 分钟前
2025年10月17日
算法
CoovallyAIHub20 分钟前
Mamba-3震撼登场!Transformer最强挑战者再进化,已进入ICLR 2026盲审
深度学习·算法·计算机视觉
Aqua Cheng.24 分钟前
代码随想录第七天|哈希表part02--454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和
java·数据结构·算法·散列表
怀揣小梦想25 分钟前
跟着Carl学算法--哈希表
数据结构·c++·笔记·算法·哈希算法·散列表
Nebula_g26 分钟前
Java哈希表入门详解(Hash)
java·开发语言·学习·算法·哈希算法·初学者
Kent_J_Truman26 分钟前
【模拟散列表】
数据结构·算法·蓝桥杯·散列表·常识类
努力努力再努力wz28 分钟前
【C++进阶系列】:万字详解unordered_set和unordered_map,带你手搓一个哈希表!(附模拟实现unordered_set和unordered_map的源码)
java·linux·开发语言·数据结构·数据库·c++·散列表
加油=^_^=29 分钟前
【C++】哈希表
数据结构·c++·散列表
Lchiyu30 分钟前
哈希表 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和
算法
对纯音乐情有独钟的阿甘30 分钟前
【C++庖丁解牛】哈希表/散列表的设计原理 | 哈希函数
c++·哈希算法·散列表