【力扣LeetCode】23 合并K个排序链表

2024-08-28 22:38

本文主要是介绍【力扣LeetCode】23 合并K个排序链表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述(难度难)

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6

链接

https://leetcode-cn.com/problems/merge-k-sorted-lists/

思路

比较好的两种思路
1、与合并两个有序链表一样,K个链表一起从头往尾走,每次选取K个链表中指针指向位置的最小值,这个最小值使用优先队列维护较为合适。
2、链表之间两两合并,可复用两个有序链表合并的代码。

  • 从第一个链表开始,依次合并后面的链表
  • 分治,第一个链表和第二个链表合并,第三个和第四个合并,如此下去
    在这里插入图片描述
    显然,分治算法是很不错的,在这里本文采用这种方法。

代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/class Solution {
public:ListNode* mergeKLists(vector<ListNode*>& lists) {if(lists.size() == 0){return NULL;}if(lists.size() == 1){return lists[0];}if(lists.size() > 1){vector<ListNode*> liststemp;if(lists.size()%2 == 0){for(int i = 0; i < lists.size(); i+=2){ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);liststemp.push_back(ans);}lists = liststemp;return mergeKLists(lists);}else{// 这里是 i < lists.size()-1 有所怀疑没有仔细确认导致浪费了一点时间查错for(int i = 0; i < lists.size()-1; i+=2){ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);liststemp.push_back(ans);}liststemp.push_back(lists[lists.size()-1]);lists = liststemp;return mergeKLists(lists);}}return NULL;}ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {ListNode* ans = NULL;if(l1 == NULL && l2 == NULL){return NULL;}else if(l1 == NULL){return l2;}else if(l2 == NULL){return l1;}else{ListNode* t1 = l1;ListNode* t2 = l2;if(t1->val < t2->val){ans = t1;t1 = t1->next;}else{ans = t2;t2 = t2->next;}ListNode* tans = ans;while(t1&&t2){if(t1->val < t2->val){tans->next = t1;t1 = t1->next;tans = tans->next;}else{tans->next = t2;t2 = t2->next;tans = tans->next;}}while(t1){tans->next = t1;t1 = t1->next;tans = tans->next;}while(t2){tans->next = t2;t2 = t2->next;tans = tans->next;}}return ans;}
};

debug代码:

#include <bits/stdc++.h>
using namespace std;struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}};class Solution {
public:ListNode* mergeKLists(vector<ListNode*>& lists) {if(lists.size() == 0){return NULL;}if(lists.size() == 1){return lists[0];}if(lists.size() > 1){vector<ListNode*> liststemp;if(lists.size()%2 == 0){for(int i = 0; i < lists.size(); i+=2){ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);liststemp.push_back(ans);}lists = liststemp;return mergeKLists(lists);}else{for(int i = 0; i < lists.size()-1; i+=2){ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);liststemp.push_back(ans);}liststemp.push_back(lists[lists.size()-1]);lists = liststemp;return mergeKLists(lists);}}return NULL;}ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {ListNode* ans = NULL;if(l1 == NULL && l2 == NULL){return NULL;}else if(l1 == NULL){return l2;}else if(l2 == NULL){return l1;}else{ListNode* t1 = l1;ListNode* t2 = l2;if(t1->val < t2->val){ans = t1;t1 = t1->next;}else{ans = t2;t2 = t2->next;}ListNode* tans = ans;while(t1&&t2){if(t1->val < t2->val){tans->next = t1;t1 = t1->next;tans = tans->next;}else{tans->next = t2;t2 = t2->next;tans = tans->next;}}while(t1){tans->next = t1;t1 = t1->next;tans = tans->next;}while(t2){tans->next = t2;t2 = t2->next;tans = tans->next;}}return ans;}
};int main()
{Solution s;ListNode* l11 = new ListNode(1);ListNode* l12 = new ListNode(4);ListNode* l13 = new ListNode(5);l11->next = l12;l12->next = l13;while(l11){cout << l11->val << endl;l11 = l11->next;}ListNode* l21 = new ListNode(1);ListNode* l22 = new ListNode(3);ListNode* l23 = new ListNode(4);l21->next = l22;l22->next = l23;ListNode* l31 = new ListNode(2);ListNode* l32 = new ListNode(6);l31->next = l32;vector<ListNode*> test;test.push_back(l11);test.push_back(l21);test.push_back(l31);ListNode* ans = s.mergeKLists(test);while(ans){cout << ans->val << " ";ans = ans->next;}return 0;
}

这篇关于【力扣LeetCode】23 合并K个排序链表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116086

相关文章

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

Java集合中的链表与结构详解

《Java集合中的链表与结构详解》链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序的通过链表中的引用链接次序实现,文章对比ArrayList与LinkedList的结构差异,详细讲解了链表... 目录一、链表概念与结构二、当向单链表的实现2.1 准备工作2.2 初始化链表2.3 打印数据、链表长

MySQL进行分片合并的实现步骤

《MySQL进行分片合并的实现步骤》分片合并是指在分布式数据库系统中,将不同分片上的查询结果进行整合,以获得完整的查询结果,下面就来具体介绍一下,感兴趣的可以了解一下... 目录环境准备项目依赖数据源配置分片上下文分片查询和合并代码实现1. 查询单条记录2. 跨分片查询和合并测试结论分片合并(Shardin

C++归并排序代码实现示例代码

《C++归并排序代码实现示例代码》归并排序将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后将排序好的子数组合并,得到排序后的数组,:本文主要介绍C++归并排序代码实现的相关资料,需要的... 目录1 算法核心思想2 代码实现3 算法时间复杂度1 算法核心思想归并排序是一种高效的排序方式,需要用

基于Python实现进阶版PDF合并/拆分工具

《基于Python实现进阶版PDF合并/拆分工具》在数字化时代,PDF文件已成为日常工作和学习中不可或缺的一部分,本文将详细介绍一款简单易用的PDF工具,帮助用户轻松完成PDF文件的合并与拆分操作... 目录工具概述环境准备界面说明合并PDF文件拆分PDF文件高级技巧常见问题完整源代码总结在数字化时代,PD

pandas数据的合并concat()和merge()方式

《pandas数据的合并concat()和merge()方式》Pandas中concat沿轴合并数据框(行或列),merge基于键连接(内/外/左/右),concat用于纵向或横向拼接,merge用于... 目录concat() 轴向连接合并(1) join='outer',axis=0(2)join='o

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与