1.题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.题解
顺序
两个两个来,用上一个的结果去和下一个合并。
class Solution
{
public:
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* mergeKLists(vector<ListNode*>& lists)
{
ListNode *ans = nullptr;
for (size_t i = 0; i < lists.size(); ++i)
{
ans = mergeTwoLists(ans, lists[i]);
}
return ans;
}
};
分治
每次合并半数链表数量的链表。
class Solution
{
public:
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);
}
};
优先队列
使用stl容器,构造结构体,存储节点的值和该节点的指针,定义默认比较函数,放入优先队列,节点自动按照从小到大顺序排好,出队入队新节点,直至队列为空结束。
class Solution
{
public:
struct Status
{
int val;
ListNode *ptr;
bool operator < (const Status &rhs) const
{
return val > rhs.val;
}
};
priority_queue <Status> q;
ListNode* mergeKLists(vector<ListNode*>& lists)
{
for (auto node: lists)
{
if (node) q.push({node->val, node});
}
ListNode head, *tail = &head;
while (!q.empty())
{
auto f = q.top();
q.pop();
tail->next = f.ptr;
tail = tail->next;
if (f.ptr->next) q.push({f.ptr->next->val, f.ptr->next});
}
return head.next;
}
};