NC51_合并k个已排序的链表

NC51_合并k个已排序的链表

知识点:归并、最小堆
题目链接

题目描述

合并 k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。

输入: [{1,2,3},{4,5,6,7}]
输出: {1,2,3,4,5,6,7}

解题思路

  1. 归并排序 注意返回值
  2. 最小堆,注意在合并的时候 需要把链表的下一个结点也放进去

代码

#include "cheader.h"
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
//1. 归并排序 时间 O(k*n*log_k) 空间 O(log_k)
class Solution {
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        return merge_sort(lists, 0, lists.size()-1);
    }
    ListNode* merge_sort(vector<ListNode*>& lists,int l,int r){
        if(l > r)
            return nullptr;
        else if(l == r)
            return lists[l];
        int mid = l + (r-l)/2;
        ListNode* n1 = merge_sort(lists, l, mid);
        ListNode* n2 = merge_sort(lists, mid+1, r);
        return merge(n1,n2);
    }
    ListNode* merge(ListNode* x,ListNode* y){
        ListNode *head = new ListNode(-1);
        ListNode *temp = head;
        while(x != nullptr && y != nullptr){
            if(x->val <= y->val){
                temp->next = x;
                x = x->next;
            }else{
                temp->next = y;
                y = y->next;
            }
            temp = temp->next;
        }
        if(x!=nullptr) temp->next = x;
        else if(y != nullptr) temp->next = y;
        return head->next;
    }
};
//2. 小根堆 时间O(k*n*log_n)  空间O(k)
class Solution {
public:
    struct compare{
        bool operator()(const ListNode* x,const ListNode* y){
            return x->val > y->val;
        }
    };
    ListNode *mergeKLists(vector<ListNode *> &lists){
        priority_queue<ListNode*,vector<ListNode*>,compare> q;
        for(ListNode* x : lists)
            if(x != nullptr)
                q.push(x);
        if(q.empty())
            return nullptr;
        ListNode* head = new ListNode(-1);
        ListNode* tmp = head;
        while(!q.empty()){
            tmp->next = q.top();
            q.pop();
            tmp = tmp->next;
            if(tmp->next) //注意要放回去 把链表的后一个元素放入
                q.push(tmp->next);
        }
        return head->next;
    }
};



今天也是爱zz的一天!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值