本专栏持续更新牛客题目解题思路及代码,欢迎感兴趣的朋友收藏⭐️专栏持续关注,共同进步
专栏直达地址:牛客刷题
描述
合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
数据范围:节点总数 0 ≤ n ≤ 5000,每个节点的val满足 ∣val∣<=1000
要求:时间复杂度 O(nlogn)
示例1
输入:[{1,2,3},{4,5,6,7}]
返回值:{1,2,3,4,5,6,7}
示例2
输入:[{1,2},{1,4,5},{6}]
返回值:{1,1,2,4,5,6}
解题思路
是BM4 合并两个排序的链表的进阶版,思路大致相同,考虑用归并排序的思想,对k个链表划分,知道变成两个有序链表进行合并的问题
需要注意的点:
- mid的取值,取得是 left 和 right 中间的值,应该是 + 而不是 -
- 递归方式
代码
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param lists ListNode类vector
* @return ListNode类
*/
// 对两个有序链表进行合并
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
if(!pHead1)
return pHead2;
else if(!pHead2)
return pHead1;
ListNode* cur1 = pHead1;
ListNode* cur2 = pHead2;
ListNode* newHead = new ListNode(0);
ListNode* cur = newHead;
while (cur1 && cur2) {
if (cur1->val >= cur2->val) {
cur->next = cur2;
cur2 = cur2->next;
} else {
cur->next = cur1;
cur1 = cur1->next;
}
cur = cur->next;
}
// 合并剩下的部分
if(cur1)
cur->next=cur1;
else
cur->next=cur2;
return newHead->next;
}
// 划分链表,直到划分成两个链表
ListNode* divList(vector<ListNode*> lists, int left, int right)
{
if(left > right)
return nullptr;
if(left == right)
return lists[left];
int mid = (right + left) / 2;
return Merge(divList(lists, left, mid), divList(lists, mid + 1, right));
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
// 归并分组排序
return divList(lists, 0, lists.size() - 1);
}
};