【力扣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

相关文章

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

基于C#实现PDF文件合并工具

《基于C#实现PDF文件合并工具》这篇文章主要为大家详细介绍了如何基于C#实现一个简单的PDF文件合并工具,文中的示例代码简洁易懂,有需要的小伙伴可以跟随小编一起学习一下... 界面主要用于发票PDF文件的合并。经常出差要报销的很有用。代码using System;using System.Col

Python中lambda排序的六种方法

《Python中lambda排序的六种方法》本文主要介绍了Python中使用lambda函数进行排序的六种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1.对单个变量进行排序2. 对多个变量进行排序3. 降序排列4. 单独降序1.对单个变量进行排序

Python视频剪辑合并操作的实现示例

《Python视频剪辑合并操作的实现示例》很多人在创作视频时都需要进行剪辑,本文主要介绍了Python视频剪辑合并操作的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录介绍安装FFmpegWindowsMACOS安装MoviePy剪切视频合并视频转换视频结论介绍

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

不删数据还能合并磁盘? 让电脑C盘D盘合并并保留数据的技巧

《不删数据还能合并磁盘?让电脑C盘D盘合并并保留数据的技巧》在Windows操作系统中,合并C盘和D盘是一个相对复杂的任务,尤其是当你不希望删除其中的数据时,幸运的是,有几种方法可以实现这一目标且在... 在电脑生产时,制造商常为C盘分配较小的磁盘空间,以确保软件在运行过程中不会出现磁盘空间不足的问题。但在

在C#中合并和解析相对路径方式

《在C#中合并和解析相对路径方式》Path类提供了几个用于操作文件路径的静态方法,其中包括Combine方法和GetFullPath方法,Combine方法将两个路径合并在一起,但不会解析包含相对元素... 目录C#合并和解析相对路径System.IO.Path类幸运的是总结C#合并和解析相对路径对于 C

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig