剑指 Offer II 078. 合并排序链表

这篇博客探讨了两种合并有序链表的方法。一种是简单的优先队列方法,另一种是利用归并排序的分治策略,将链表两两合并。这两种方法都是为了高效地整合多个已排序的链表,生成一个单一的有序链表。

给定一个链表数组,每个链表都已经按升序排列。
请将所有链表合并到一个升序链表中,返回合并后的链表。

示例 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

第一时间想到的是个笨方法,就是先比较每个链表的首节点,将最小的拿出来放入result,被拿出来的链表指针前进一个节点,然后再比较所有链表首节点,以此类推。

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        auto cmp=[](ListNode* node1, ListNode* node2)->bool{return node1->val>node2->val;};
        priority_queue<ListNode*,vector<ListNode*>,decltype(cmp)> q(cmp);
        for(ListNode* node: lists)
        {
            if(node!=nullptr)
                q.push(node);
        }
        ListNode* cur=new ListNode(0);
        ListNode* res=cur;
        while(!q.empty())
        {
            ListNode* node = q.top();
            q.pop();
            if(node->next!=nullptr)
            {
                q.push(node->next);
            }
            cur->next = node;
            cur = cur->next;
        }
        return res->next;
    }
};

在这里插入图片描述
昨晚之后看评论区的骚操作,用归并排序,两两合并。(分治法)
代码:

class Solution {
public:
    // 合并两个有序链表
    ListNode* merge(ListNode* p1, ListNode* p2){
        if(!p1) return p2;
        if(!p2) return p1;
        if(p1->val <= p2->val){
            p1->next = merge(p1->next, p2);
            return p1;
        }else{
            p2->next = merge(p1, p2->next);
            return p2;
        }
    }
    //将k个链表依次拆分;
    ListNode* mergelist(vector<ListNode*>& lists, int start, int end){
        //必须确保start<end才进行合并,start=end时返回自身即可;
        if(start==end){
            return lists[start];
        }
        else if(start<end){
            int mid = (start + end) / 2;
            ListNode* l1 = mergelist(lists, start, mid);
            ListNode* l2 = mergelist(lists, mid+1, end);
            return merge(l1, l2);
        }
        else{
            return NULL;
        }
    }

    //依次进行两两合并
    ListNode* mergeKLists(vector<ListNode*>& lists) {
       return mergelist(lists, 0, lists.size()-1);
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值