合并k个已排序的链表(C++)

问题描述

合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。

数据范围:节点总数 0≤n≤50000≤n≤5000,每个节点的val满足 ∣val∣<=1000∣val∣<=1000

要求:时间复杂度 O(nlogn)O(nlogn)

示例1

输入:

[{1,2,3},{4,5,6,7}]

返回值:

{1,2,3,4,5,6,7}

示例2

输入:

[{1,2},{1,4,5},{6}]

返回值:

{1,1,2,4,5,6}

解题思路

逐步找到所有链表头节点中值最小的节点,将其加入结果链表,同时将对应链表的头节点向后移动,直到所有链表都为空。

合并过程演示

代码实现

 ListNode* mergeKLists(vector<ListNode*>& lists) {
        // write code here
        ListNode* rhead = nullptr;
        ListNode* rtail = nullptr;
        while (true) 
        {
            int minIndex = -1;
            int i = lists.size();
            while (i--) 
            {
                if (lists[i] != nullptr ) 
                {
                    if (minIndex == -1) 
                    {
                        minIndex = i;
                    }
                    else if (lists[i]->val < lists[minIndex]->val) 
                    {
                        minIndex = i;
                    }
                }
            }
            if (minIndex == -1) 
            {
                return rhead;
            }
            if (rhead == nullptr) 
            {
                rhead = rtail = lists[minIndex];
            }
            else 
            {
                rtail->next = lists[minIndex];
                rtail = rtail->next;
            }
            lists[minIndex] = lists[minIndex]->next;
        }
    }

代码解析

1. 初始化合并链表头指针和尾指针

        使用 rhead 保存最终合并链表的头节点,用于返回结果。

        使用 rtail 辅助插入新节点。

ListNode* rhead = nullptr; 
ListNode* rtail = nullptr;

2. 遍历链表数组,查找当前最小节点

        使用 minIndex 记录值最小节点所在链表的索引。

        遍历所有链表头节点,比较值大小更新 minIndex

int minIndex = -1; 
int i = lists.size();
while (i--) 
{
    if (lists[i] != nullptr) 
    {
        if (minIndex == -1 || lists[i]->val < lists[minIndex]->val) 
        {
            minIndex = i;
        }
    }
}

3. 判断退出条件

        当所有链表都遍历完成(即 minIndex == -1),返回结果链表头节点。

if (minIndex == -1) 
{
    return rhead;
}

4. 更新合并链表

        若合并链表为空(第一次插入节点),将最小值节点作为头节点。

        否则,追加最小值节点到尾部。

if (rhead == nullptr) 
{
    rhead = rtail = lists[minIndex];
} 
else 
{
    rtail->next = lists[minIndex];
    rtail = rtail->next;
}

5. 移动链表头节点

        将已插入节点的链表头指针向后移动,继续下一次循环。

lists[minIndex] = lists[minIndex]->next;

总结

本文实现了逐步查找最小值的 mergeKLists 方法,逻辑直观且易于实现,但在 kkk 较大时效率较低。实际应用中,结合优先队列或分治法可以显著优化性能。读者可以根据具体需求选择合适的实现方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值