23. Merge k Sorted Lists

发布于:2025-06-03 ⋅ 阅读:(21) ⋅ 点赞:(0)

目录

题目描述

方法一、k-1次两两合并

方法二、分治法合并

方法三、使用优先队列


题目描述

23. Merge k Sorted Lists

方法一、k-1次两两合并

选第一个链表作为结果链表,每次将后面未合并的链表合并到结果链表中,经过k-1次合并,即可得到答案。假设每个链表的最长长度是n,时间复杂度O(n+2n+3n+...(k-1)n) = O(\frac{k(k-1))}{2}n) = O(k^{2}n)。空间复杂度O(1)。

/**
 * 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) {
        int n = lists.size();
        if(n == 0)
            return nullptr;
        ListNode* ans = lists[0];
        for(int i = 1;i< n;i++){
            ans = merge(ans,lists[i]);
        }
        return ans;
    }

    ListNode* merge(ListNode* L1,ListNode* L2){
        ListNode* dummy = new ListNode();
        ListNode* cur = dummy;
        while(L1&&L2){
            if(L1->val < L2->val){
                cur->next = L1;
                cur = L1;
                L1 = L1->next;
            }else{
                cur->next = L2;
                cur = L2;
                L2 = L2->next;
            }
        }
        cur->next = L1 != nullptr ? L1 : L2;
        ListNode* res = dummy->next;
        delete dummy;
        return res;
    }
};

方法二、分治法合并

时间复杂度 O(kn×logk)。空间复杂度 O(logk) 。

/**
 * 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) {
        int n = lists.size();
        if(n == 0)
            return nullptr;

        return merge(lists,0,n-1);
    }

    ListNode* merge(vector<ListNode*>& lists,int left,int right){
        if(left == right)
            return lists[left];
        if(left>right)
            return nullptr;
        int mid = left + ((right-left)>>1);
        return mergeTwoList(merge(lists,left,mid),merge(lists,mid+1,right));
    }

    ListNode* mergeTwoList(ListNode* L1,ListNode* L2){
        ListNode* dummy = new ListNode();
        ListNode* cur = dummy;
        while(L1&&L2){
            if(L1->val < L2->val){
                cur->next = L1;
                cur = L1;
                L1 = L1->next;
            }else{
                cur->next = L2;
                cur = L2;
                L2 = L2->next;
            }
        }
        cur->next = L1 != nullptr ? L1 : L2;
        ListNode* res = dummy->next;
        delete dummy;
        return res;
    }
};

方法三、使用优先队列

时间复杂度 O(kn×logk)。空间复杂度 O(k) 。

/**
 * 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 {
    struct Node{
        ListNode* node_ptr;
        int val;
        bool operator<(const Node& rhs) const{
            return val>rhs.val;
        }
    };
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<Node> Heap;
        for(auto& node:lists){
            if(node){
                Heap.push({node,node->val});
            }
        }
        ListNode* head = nullptr;
        ListNode* cur = nullptr;
        while(!Heap.empty()){
            if(head == nullptr){
                head = Heap.top().node_ptr;
                cur = head;
            }else{
                cur->next = Heap.top().node_ptr;
                cur = cur->next;
            }
            Heap.pop();
            if(cur->next){
                Heap.push({cur->next,cur->next->val});
            }
        }
        return head;
    }
};

网站公告

今日签到

点亮在社区的每一天
去签到