LeetCode-23 合并K个升序链表

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists

题目描述

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

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

 

示例 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 <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4

解题思路

使用暴力法,每次取最小的链表头,并且更新链表组的数据。时间复杂度为O(k2n),我们可以维护一个优先队列来代替每次找最小值的过程,这样时间复杂度就可以缩短为O(knlogk)。

同样,我们使用分冶的思路,将链表每次两两合并,由于单次合并的时间复杂度为O(n),那么时间复杂度也可以达到O(knlogk)。

代码展示

复制代码
/**
 * 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* mergeKLists(vector<ListNode*>& lists) {
        ListNode *pHead = new ListNode(-1);
        ListNode *pCur = pHead;
        int iNull = 0;
        for(auto iter: lists)
        {
            if(iter != nullptr)
                iNull++;
        }
        while(iNull)
        {
            int iMin = INT_MAX;
            ListNode* qCur = nullptr;
            int iIndex = -1;
            for(int i = 0; i < lists.size(); i++)
            {
                if(lists[i])
                {
                    if(lists[i]->val < iMin)
                    {
                        qCur = lists[i];
                        iIndex = i;
                        iMin = lists[i]->val;
                    }
                }
            }
            pCur->next = qCur;
            lists[iIndex] = qCur->next;
            if(!lists[iIndex])
                iNull--;
            qCur->next = nullptr;
            pCur = qCur;
        }
        return pHead->next;
    }
};
复制代码

优先队列方法:

复制代码
/**
 * 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* mergeKLists(vector<ListNode*>& lists) {
        ListNode *pHead = new ListNode(-1);
        ListNode *pCur = pHead;
        struct cmp
        {
            bool operator() (ListNode *a, ListNode*b)
            {
                return a->val > b->val; 
            }
        };

        priority_queue<ListNode*, vector<ListNode*>, cmp> pqueue;
        for(auto iter: lists)
        {
            if(iter)
                pqueue.push(iter);
        }
        while(!pqueue.empty())
        {
            ListNode* qCur = pqueue.top();
            pqueue.pop();
            pCur->next = qCur;
            if(qCur->next)
                pqueue.push(qCur->next);
            qCur->next = nullptr;
            pCur = qCur;
        }
        return pHead->next;
    }
};
复制代码

分冶方法:

复制代码
/**
 * 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* mergeList(ListNode* p, ListNode*q)
    {
        ListNode *pHead = new ListNode(-1);
        ListNode *pCur = pHead;
        while(p && q)
        {
            if(p->val > q->val)
            {
                pCur->next = q;
                q = q->next;
                pCur = pCur->next;
            }
            else
            {
                pCur->next = p;
                p = p->next;
                pCur = pCur->next;
            }
        } 
        if(p)
            pCur->next = p;
        if(q)
            pCur->next = q;
        return pHead->next; 
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        int iStep = 1;
        if(lists.size() == 0)
            return nullptr;
        while(iStep < lists.size())
        {
            for(int i = 0; i + iStep < lists.size(); i += 2 * iStep)
            {
                lists[i] = mergeList(lists[i], lists[i + iStep]);
            }
            iStep *= 2;
        }
        return lists[0];
    }
};
复制代码

 

运行结果

 

 

 

 

posted @   过客匆匆,沉沉浮浮  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示