当前位置:网站首页>合并k个已排序的链表
合并k个已排序的链表
2022-08-10 21:49:00 【干饭小白】

ojbk...开始以为这题没有内存要求,所以就用来一个很简单的方法合并。创建第三条链表,结果部分案例过不去。

这个代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergetK(ListNode *A,ListNode *B)
{
ListNode *C = nullptr;
ListNode *ans = nullptr;
while(A != nullptr && B != nullptr)
{
ListNode *s = new ListNode(0);
if(A->val > B->val)
{
s->val = B->val;
s->next = nullptr;
B = B->next;
}
else
{
s->val = A->val;
s->next = nullptr;
A = A->next;
}
if(C == nullptr)
{
C = s;
ans = C;
}
else
{
C->next = s;
C = C->next;
}
}
while(A != nullptr)
{
ListNode *s = new ListNode(0);
s->val = A->val;
s->next = nullptr;
if(C == nullptr)
{
C = s;
ans = C;
}
else
{
C->next = s;
C = C->next;
}
A = A->next;
}
while(B != nullptr)
{
ListNode *s = new ListNode(0);
s->val = B->val;
s->next = nullptr;
if(C == nullptr)
{
C = s;
ans = C;
}
else
{
C->next = s;
C = C->next;
}
B = B->next;
}
return ans;
}
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.empty())
{
return nullptr;
}
ListNode *ans;
ans = lists[0];
for(int i=1;i<lists.size();i++)
{
ans = mergetK(ans,lists[i]);
}
return ans;
}
};好吧,看来不能创建新的节点,只能用辅助指针了。。。。。(这题就是合并两个有序链表,水题)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergetK(ListNode *A,ListNode *B)
{
ListNode *pA = A;
ListNode *pB = B;
ListNode *ans = nullptr;
ListNode *head = nullptr;
while(A != nullptr && B != nullptr)
{
if(A->val <= B->val)
{
if(ans == nullptr)
{
ans = A;
head = A;
}
else
{
head->next = A;
head = head->next;
}
//pA = A;
A = A->next;
}
else
{
if(ans == nullptr)
{
ans = B;
head = B;
}
else
{
head->next = B;
head = head->next;
}
//pB = B;
B = B->next;
}
}
if(A != nullptr)
{
head->next = A;
}
if(B != nullptr)
{
head->next = B;
}
return ans;
}
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.empty())
{
return nullptr;
}
ListNode *ans;
ans = lists[0];
for(int i=1;i<lists.size();i++)
{
if(lists[i] == nullptr)
{
continue;
}
ans = mergetK(ans,lists[i]);
}
return ans;
}
};我去,超时.....
![]()
看来这题没有想的那么简单呀....
分析下代码的时间复杂度,,,,
遍历 litsts O(n)
内部:等于遍历了一遍 链表 O(n+m)
这么算:O(n^2)
看题目要求的是时间复杂度 O(nlogk)
k是链表的个数:说明只能从 遍历 litsts开了。。。。
根据经验,合并两个有序链表时间复杂度最优 O(n+m) 再一次说明 只能从 遍历 litsts优化了
等等,logK对数时间,第一反应应该是二分吧。我去,说不定可以解决
二分的前提:保证有序,nice,题目的条件刚好是有序的(因为数组下标是递增的呀)
优化后:

我操,终于过了。。。。。感动,落泪。一个小时呜呜....
两个链表的合并:(前面的代码有点小bug,有一种情况需要特殊处理)
当一个链表尾空时:(此时应该不需要合并)
[{-9},{},{-10,-8,-2,-1,2},{-10,-9,-7,-6,-5,-2,-2,1,4},{-7,-7,-1,0,4},{},{-4,0},{-9,-6,-5,-5,-2,2,3,3}]
更改:做个特判,两个有序链表的合并就不说了,只要你认真一点就一定能写出来。
合并两个有序链表代码:
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* merge(ListNode *A,ListNode *B)
{
//特判 (A=nullptr && B=nullptr) 或者
// (A=nullptr && B!=nullptr) 或者 (A!=nullptr && B=nullptr)
if(A == nullptr || B == nullptr)
{
return A==nullptr ? B:A;
}
ListNode *head = nullptr;
ListNode *ans = nullptr;
while(A != nullptr && B != nullptr)
{
if(A->val <= B->val)
{
if(ans == nullptr)
{
ans = A;
head = A;
}
else
{
head->next = A;
head = head->next;
}
A = A->next;
}
else
{
if(ans == nullptr)
{
ans = B;
head = B;
}
else
{
head->next = B;
head = head->next;
}
B = B->next;
}
}
if(A != nullptr)
{
head->next = A;
}
if(B != nullptr)
{
head->next = B;
}
retrun ans;
}
二分的思路及代码:
对于二分有两种方法:递归(推荐使用) 非递归
通常我们使用递归就行,好分析,好写代码

我们先看一个例子来分析:
先分成两半: A和B的处理过程一定要是一样的(或者说将一个整体划分为两个与这个整体相同的子问题)
假设将A和B成最小的子问题了,此时我们应该干嘛????
当然是进行链表合并咯。。。。
好的我们来合并吧,又看,A和B还没划分到最小呀。(递归是一个自顶向下的过程)
为什么我这里说要把A和B看作最小的子问题呢??这个是作者对递归的特别理解吧,如果画出解空间,递归是不是需要回溯,当我们回溯到这一层的时候是不是需要合并 A和B.
ok....为了方便理解我们不妨就把每次状态都当作最小问题,对于最小问题的求解什么样的,我们就怎么处理就行了,而且本来就数划分为与子问题一样的问题吗,只是规模遍历而已。
我们继续划分

我们写代码吧(二分代码)
//返回值看我上面画的图
ListNode* binary_lists(vector<ListNode *> &lists,int l,int r)
{
//先写边界条件(出口)
if(l == r)
{
return lists[l];
}
if(l > r)
{
return nullptr;
}
int mid = (l+r)/2;
//合并 A和B 因为回溯到这个点的时候需要合并A和B
return merge(binary_lists(lists,l,mid),binary_lists(lists,mid+1,r));
}okk...
我们把所有的代码合在一起吧
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *ans1;
ListNode* merget(ListNode *A,ListNode *B)
{
if(A == nullptr || B == nullptr)
{
return A == nullptr ? B:A;
}
ListNode *pA = A;
ListNode *pB = B;
ListNode *ans = nullptr;
ListNode *head = nullptr;
while(A != nullptr && B != nullptr)
{
if(A->val <= B->val)
{
if(ans == nullptr)
{
ans = A;
head = A;
}
else
{
head->next = A;
head = head->next;
}
//pA = A;
A = A->next;
}
else
{
if(ans == nullptr)
{
ans = B;
head = B;
}
else
{
head->next = B;
head = head->next;
}
//pB = B;
B = B->next;
}
}
if(A != nullptr)
{
head->next = A;
}
if(B != nullptr)
{
head->next = B;
}
return ans;
}
ListNode* merList(vector<ListNode *> &lists,int l,int r)
{
if(l == r) //只有一条
{
return lists[l];
}
if( l > r)
{
return nullptr;
}
int mid = (l + r)/2;
return merget(merList(lists,l,mid),merList(lists,mid+1,r));
}
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.empty())
{
return nullptr;
}
// ans = lists[0];
// for(int i=1;i<lists.size();i++)
// {
// if(lists[i] == nullptr)
// {
// continue;
// }
// ans = mergetK(ans,lists[i]);
// }
return merList(lists,0,lists.size()-1);
}
};
小结:创作不易,点个关注支持一下吧
如果有喜欢C++的同学可以观看作者的其他专栏,全套C++都在更新(从C++基础到Linux系 统编程、网络编程 数据编程等等... 并且有一个完整C++项目)
边栏推荐
- 2022.8.8好题选讲(数论场)
- These must-know JVM knowledge, I have sorted it out with a mind map
- 从斐波那契 - 谈及动态规划 - 优化
- RTL8721DM 双频WIFI + 蓝牙5.0 物联网(IoT)应用
- Extended Chinese Remainder Theorem
- 如何保护 LDAP 目录服务中的用户安全?
- LeetCode Daily Question (1573. Number of Ways to Split a String)
- labelme-屏蔽拖拽的事件
- C # Hex file transfer skills necessary article 】 【 bin file code implementation
- The perfect alternative to domestic Gravatar avatars Cravatar
猜你喜欢

shell脚本循环语句for、while语句

使用SylixOS虚拟串口,实现系统串口自由

shell编程之正则表达式与文本处理器

mmpose关键点(一):评价指标(PCK,OKS,mAP)

阿里云张新涛:支持沉浸式体验应用快速落地,阿里云云XR平台发布

异常的了解

交换机和生成树知识点

FPGA - Memory Resources of 7 Series FPGA Internal Structure -03- Built-in Error Correction Function

新一代网络安全防护体系的五个关键特征

FPGA - 7系列 FPGA内部结构之Memory Resources -03- 内置纠错功能
随机推荐
艺术与科技的狂欢,阿那亚2022砂之盒沉浸艺术季
Service - DNS forward and reverse domain name resolution service
labelme-5.0.1版本编辑多边形闪退
How to translate financial annual report, why choose a professional translation company?
黑猫带你学Makefile第12篇:常见Makefile问题汇总
Application of Spatial 3D Model Reconstruction Based on Pix4Dmapper - Spatial Analysis and Site Selection
[Maui official version] Create a cross-platform Maui program, as well as the implementation and demonstration of dependency injection and MVVM two-way binding
关于 DataFrame: 处理时间
labelme - block drag and drop events
带着昇腾去旅行:一日看尽金陵城里的AI胜景
力扣221题,最大正方形
Thread State 详解
labelme-屏蔽拖拽的事件
mmpose关键点(一):评价指标(PCK,OKS,mAP)
ThreadLocal comprehensive analysis (1)
ArcMap创建镶嵌数据集、导入栅格图像并修改像元数值显示范围
阿里云架构师金云龙:基于云XR平台的视觉计算应用部署
Black cats take you learn Makefile article 13: a Makefile collection compile problem
论文解读(g-U-Nets)《Graph U-Nets》
LeetCode每日一题(1573. Number of Ways to Split a String)