C/C++ BM5 合并K个已排序的链表

文章目录

  • 前言
  • 题目
  • 1 解决方案一
    • 1.1 思路阐述
    • 1.2 源码
  • 2 解决方案二
    • 2.1 思路阐述
    • 2.2 源码
  • 总结

前言

在接触了BM4的两个链表合并的情况,对于k个已排序列表,其实可以用合并的方法来看待问题。

这里第一种方法就是借用BM4的操作,只不过是多个合并的情况。

第二种方法是把所有的链表变成一个链表,再排序输出。调用STL库的话,这题就很取巧了。


题目

在这里插入图片描述

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

数据范围:节点总数 0≤n≤5000,每个节点的val满足 ∣val∣<=1000
要求:时间复杂度 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}

1 解决方案一

1.1 思路阐述

这个方案主要就是借助BM4的解法,无论哪一种都行。将原来两个链表的表变成,一个链表与一个存放链表容器中的每一个链表合并的过程。

比如对于vector容器lists,存放链表。对于lists[0]和lists[1]两个链表,在BM4中就是对应的两个有序链表合并;合并后的链表这里简称finalList,接下来就是这个finalList和lists容器中的下一个链表进行合并。重复上面的操作,直到容器内取完所有链表。

这里finalList是一个哨兵节点,是为了保证实际链表中的每一个节点都有前驱结点。

1.2 源码

#include <cstdlib>
#include <vector>
class Solution {public:ListNode* mergeKLists(vector<ListNode*>& lists) {//如果为空则返回空if(!lists.size())return nullptr;ListNode* finalList=new ListNode(-1);finalList->next=lists[0];//这里i为什么从1开始,是因为lists[0]作为finalList的初始链表了for(int i=1;i<lists.size();i++){//int j=i+1;finalList->next=Merge(finalList->next,lists[i]) ;               }return finalList->next;}//下面的这个Merge函数就是BM4的一个解法,BM4有两个解法,这里我挑了一个比较好理解的。ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {ListNode* rec = new ListNode(-1);if (!pHead1 && !pHead2) {return nullptr;}if (!pHead1 && pHead2) {return pHead2;}if (pHead1 && !pHead2) {return pHead1;}//比较链表大小bool firstListBig = true;if (pHead1->val > pHead2->val) {firstListBig = true;rec->next = pHead2;} else {firstListBig = false;rec->next = pHead1;}//第二个链表大的情况if (!firstListBig) {while (pHead2 && pHead1) {if (!pHead1->next) {pHead1->next = pHead2;break;}ListNode* tempNode = pHead2->next;if (pHead2->val <= pHead1->next->val) {pHead2->next = pHead1->next;pHead1->next = pHead2;pHead2 = tempNode;pHead1 = pHead1->next;} else {pHead1 = pHead1->next;if (!pHead1->next) {pHead1->next = pHead2;break;}}}} else { //第二个链表小的情况while (pHead2 && pHead1) {if (!pHead2->next) {pHead2->next = pHead1;break;}ListNode* tempNode = pHead1->next;if (pHead1->val <= pHead2->next->val) {pHead1->next = pHead2->next;pHead2->next = pHead1;pHead1 = tempNode;pHead2 = pHead2->next;} else {pHead2 = pHead2->next;if (!pHead2->next) {pHead2->next = pHead1;break;}}}}return rec->next;}};

2 解决方案二

2.1 思路阐述

不考虑BM4的解法,这道题拿到手的第一反应,有一堆链表要合并成一个升序链表。

那最简单的方法不就是把所有链表接到一起,再用排序算法做一下咯。

这里的难点吧,我个人绝对就是对stl的使用熟练与否,以及对于特殊情情况空链表的话,怎么判断。

在C++中,std::vector 是标准模板库(STL)提供的动态数组容器。它提供了动态大小的数组,可以在运行时动态地增加或减少其大小。std::vector 是一个非常灵活和常用的容器,用于存储一系列元素。

std::vector 是一个非常常用的容器,特别适合需要频繁访问元素、动态改变大小的情况。需要注意的是,由于在中间或头部插入/删除元素的代价相对较高,如果需要频繁在中间插入或删除元素,可能需要考虑其他容器,比如 std::list。

2.2 源码

#include <cstdlib>
#include <vector>
#include <algorithm>
class Solution {public:ListNode* mergeKLists(vector<ListNode*>& lists) {//用来返回的容器vector <int> vec;//如果传入的链表容器为空则直接返回if (lists.size() == 0)return NULL;//将链表容器的链表中的所有值插入到返回容器vec中for (int i = 0; i < lists.size(); ++i) {ListNode* p = lists[i];while (p) {vec.push_back(p->val);p = p->next;}}//使用stl容器库的sort(这个是快排)sort(vec.begin(), vec.end());//对于链表容器是空的情况,虽然size>0,但是插入到vec的值其实还是空的,所以这里还要返回NULLif (vec.size() == 0)return NULL;//把vec的所有值全部放到新的链表中去,返回一个新的链表即可。ListNode* head = new ListNode(vec[0]);ListNode* p = head;for (int i = 1; i < vec.size(); ++i) {p->next = new ListNode(vec[i]);p = p->next;}return head;}};

总结

这道题是BM4的延伸,主要是多了一个两两合并的思想,对于解法二,就是有点取巧的意思了,就题论题这种。

对于解法2的sort,涉及到的是排序算法:快速排序。这个后面还是要自己手写一遍快排。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/414579.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年全球软件质量效能大会(QECon深圳站):核心内容与学习收获(附大会核心PPT下载)

随着科技的快速发展&#xff0c;软件行业面临着越来越多的挑战和机遇。为了更好地应对这些挑战&#xff0c;不断提升软件的质量和效能&#xff0c;大会将汇聚全球的软件开发者、架构师和项目经理&#xff0c;共同探讨和分享关于软件质量保证、测试、性能优化、用户体验设计、人…

排序链表(LeetCode 148)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路参考文献 1.问题描述 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4]示例 2&#xff1a; 输入&#xff…

多色女童家居服,柔软细腻超舒适

柔软细腻到不想脱下来的 优可丝面料家居服来啦 精挑细选的可爱印花图案 让宝贝能够更快乐的进入梦乡 长度也是刚刚好合适 春夏交替的季节&#xff0c;建议多入几件换着穿

如何通过人才测评体系,进行科学的人才培养?

企业与企业之间的竞争&#xff0c;说白了就是人才之间的竞争&#xff0c;因为高素质人才可以有更先进的技术、更灵活的思想、更优秀的沟通协作能力&#xff0c;这样企业可以更高效的发展&#xff0c;从而更有竞争力&#xff0c;那么对于企业而言&#xff0c;建立人才测评系统&a…

访问者模式介绍

目录 一、访问者模式介绍 1.1 访问者模式定义 1.2 访问者模式原理 1.2.1 访问者模式类图 1.2.2 模式角色说明 二、访问者模式的应用 2.1 需求说明 2.2 需求实现 2.2.1 V1版本 2.2.1.1 抽象产品类 2.2.1.2 糖果类 2.2.1.3 酒水类 2.2.1.4 水果类 2.2.1.5 访问者接口…

轻量化/高效扩散模型文献综述

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

Dubbo-admin监控中心

监控中心 Dubbo-admin监控中心执行操作启动provider和consumer项目进行测试总体流程 Dubbo-admin监控中心 dubbo-admin下载路径 git clone https://github.com/apache/dubbo-admin.git图1-1 dubbo-admin项目文件展示 执行操作 # 启动zookeeper# 前端 cd dubbo-admin-ui npm i…

投资有道:分析、交易与等待的艺术

投资过程可以分为分析、交易和等待三个阶段。在这三个阶段中&#xff0c;分析和交易是相互联系的&#xff0c;而等待则是连接这两端的关键。分析的核心在于具备商业理解力和概率思维&#xff0c;而交易的核心则在于掌握赔率和逆向思维。在这三个阶段中&#xff0c;等待是最难把…

用 CloudCanal 做跨互联网数据库双向同步

简介 CloudCanal 推出 跨互联网安全数据同步 方案之后&#xff0c;有一些商业客户落地&#xff0c;效果良好&#xff0c;不过客户也反馈了一些改进和新需求&#xff0c;其中最大的一个需求即双向同步防循环。 近期 CloudCanal 版本支持了这个特性&#xff0c;整体方案进一步升…

【小笔记】时序数据分类算法最新小结

2024.1.15 最近基于时序数据训练分类算法&#xff0c;对其进行了一番了解&#xff0c;主要围绕以下几点&#xff1a; 时序数据算法有哪些细分类&#xff1f;时序数据分类算法经典模型&#xff1f;当下时序分类算法模型强baseline&#xff1f;有没有现成的工具&#xff1f; 1…

Prometheus 监控MySQL

监控MySQL运行状态&#xff1a;MySQLD Exporter MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB公司开发&#xff0c;目前属于Oracle旗下的产品。 MySQL是最流行的关系型数据库管理系统之一。数据库的稳定运行是保证业务可用性的关键因素之一。这一小节当中将介绍…

用于自动驾驶最优间距选择和速度规划的多配置二次规划(MPQP) 论文阅读

论文链接&#xff1a;https://arxiv.org/pdf/2401.06305.pdf 论文题目&#xff1a;用于自动驾驶最优间距选择和速度规划的多配置二次规划&#xff08;MPQP&#xff09; 1 摘要 本文介绍了用于自动驾驶最优间距选择和速度规划的多配置二次规划&#xff08;MPQP&#xff09;。…