IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 合并K个升序链表 -> 正文阅读

[数据结构与算法]合并K个升序链表

题目

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

数据范围:节点总数满足 0≤n≤1050 \le n \le 10^50≤n≤105,链表个数满足 1≤k≤105 1 \le k \le
10^5 \ 1≤k≤105 ,每个链表的长度满足 1≤len≤200 1 \le len \le 200 \ 1≤len≤200
,每个节点的值满足 ∣val∣<=1000|val| <= 1000∣val∣<=1000 要求:时间复杂度
O(nlogk)O(nlogk)O(nlogk)

示例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* mergeTwoLists(ListNode* pHead1,ListNode* pHead2)
    {
    	//如果有一个链表为空,直接返回拎一个链表
        if(pHead1 == NULL) return pHead2;
        if(pHead2 == NULL) return pHead1;

		//添加一个头结点
        ListNode* res = new ListNode(0);
        ListNode* cur =res;
        
        //将链表的值一个一个的连到目标链表当中
        while(pHead1 && pHead2)
        {
            if(pHead1->val < pHead2->val)
            {
                cur->next = pHead1;
                pHead1 =pHead1->next;
            }
            else
            {
                cur->next = pHead2;
                pHead2 = pHead2->next;
            }
            cur = cur->next;
        }

		//将剩余的链表链到目标链表当中
        if(pHead1 != NULL) cur->next = pHead1;
        if(pHead2 != NULL) cur->next = pHead2;
        
        //返回合并的链表
        return res->next;
    }

那么新的问题有来了,我们如何将时间复杂度降到O(nlongK)呢?

这个时候让我想起了简单快速排序,快排的时间复杂度不就是O(nlogN)嘛。
那能不能仿照快排的方式,将链表的集合进行划分,然后递归的去归并呢?事实是可以的,我们从中间开始划分,不断地递归,知道我们的链表数只剩下两个或者一个的时候,进行合并,然后再不断地拼接,最终得到我们想要的链表

流程图:
在这里插入图片描述

看实现:

//划分合并区间
    ListNode* Partition(vector<ListNode*> &lists,int left,int right)
    {
        if(left > right)
        {
            return NULL;
        }
        else if(left == right)
        {
            return lists[left];
        }
        
        int mid = (right-left)/2+left;
        
        return mergeTwoLists(Partition(lists, left, mid), Partition(lists, mid+1, right));
    }

整体代码:

class Solution {
public:
    //合并两个链表
    ListNode* mergeTwoLists(ListNode* pHead1,ListNode* pHead2)
    {
        if(pHead1 == NULL) return pHead2;
        if(pHead2 == NULL) return pHead1;
        ListNode* res = new ListNode(0);
        ListNode* cur =res;
        
        while(pHead1 && pHead2)
        {
            if(pHead1->val < pHead2->val)
            {
                cur->next = pHead1;
                pHead1 =pHead1->next;
            }
            else
            {
                cur->next = pHead2;
                pHead2 = pHead2->next;
            }
            cur = cur->next;
        }
        if(pHead1 != NULL) cur->next = pHead1;
        if(pHead2 != NULL) cur->next = pHead2;
        
        return res->next;
    }
    
    //划分合并区间
    ListNode* Partition(vector<ListNode*> &lists,int left,int right)
    {
        if(left > right)
        {
            return NULL;
        }
        else if(left == right)
        {
            return lists[left];
        }
        
        int mid = (right-left)/2+left;
        
        return mergeTwoLists(Partition(lists, left, mid), Partition(lists, mid+1, right));
    }
    
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        return Partition(lists, 0, lists.size()-1);
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:28:41  更:2022-05-24 18:30:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:03:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码