leetcode 23. 合并 K 个升序链表
题目链接:https://leetcode.cn/problems/merge-k-sorted-lists/
第一种写法,不断将未排序的链表插入到一个已经排序的链表中。
这样写的问题在于,当未排序的链表逐渐变的很大时,每插入一个新链表,都会来一次O(kn),总时间复杂度为O(k²n)
我们可以通过分治,快速的消灭未排序链表个数,这样可以达到O(kn logk)
非分治写法:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.empty()) {
return nullptr;
}
ListNode* head = nullptr;
int i = 0;
while (i < lists.size() && !lists[i]) { i++; }
if (i >= lists.size()) { return nullptr; }
head = lists[i++];
for (; i < lists.size(); ++i) {
ListNode* p = lists[i];
ListNode* phead = head;
while (p) {
if (p->val <= head->val) {
ListNode* tmp = p->next;
p->next = head;
head = p;
phead = head;
p = tmp;
continue;
}
while (phead->next && p->val > phead->next->val) {
phead = phead->next;
}
ListNode* tmp = p->next;
p->next = phead->next;
phead->next = p;
p = tmp;
}
}
return head;
}
分治写法:
注意这一句 return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
,有点绕
ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
if ((!a) || (!b)) return a ? a : b;
ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
while (aPtr && bPtr) {
if (aPtr->val < bPtr->val) {
tail->next = aPtr;
aPtr = aPtr->next;
} else {
tail->next = bPtr;
bPtr = bPtr->next;
}
tail = tail->next;
}
tail->next = (aPtr ? aPtr : bPtr);
return head.next;
}
ListNode* merge(vector <ListNode*> &lists, int l, int r) {
if (l == r) return lists[l];
if (l > r) return nullptr;
int mid = (l + r) >> 1;
return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
return merge(lists, 0, lists.size() - 1);
}
本文来自博客园,作者:linukey,转载请注明原文链接:https://www.cnblogs.com/linukey/p/17417148.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix