【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;
    }
};
相关推荐
虾球xz41 分钟前
游戏引擎学习第276天:调整身体动画
c++·学习·游戏引擎
虾球xz42 分钟前
游戏引擎学习第275天:将旋转和剪切传递给渲染器
c++·学习·游戏引擎
AndrewHZ1 小时前
【图像处理基石】什么是油画感?
图像处理·人工智能·算法·图像压缩·视频处理·超分辨率·去噪算法
.格子衫.1 小时前
015枚举之滑动窗口——算法备赛
数据结构·算法
J先生x2 小时前
【IP101】图像处理进阶:从直方图均衡化到伽马变换,全面掌握图像增强技术
图像处理·人工智能·学习·算法·计算机视觉
爱coding的橙子4 小时前
每日算法刷题 Day3 5.11:leetcode数组2道题,用时1h(有点慢)
算法·leetcode
虾球xz6 小时前
游戏引擎学习第268天:合并调试链表与分组
c++·学习·链表·游戏引擎
fpcc6 小时前
跟我学c++高级篇——模板元编程之十三处理逻辑
c++
格林威7 小时前
Baumer工业相机堡盟工业相机的工业视觉中为什么偏爱“黑白相机”
开发语言·c++·人工智能·数码相机·计算机视觉
Dream it possible!8 小时前
LeetCode 热题 100_只出现一次的数字(96_136_简单_C++)(哈希表;哈希集合;排序+遍历;位运算)
c++·leetcode·位运算·哈希表·哈希集合