1. 解法一
解题思路:
- 将第一次链表依次和后边链表合并,将合并结果保存在第一个链表里边,代码如下:
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
if(n == 0) return nullptr;
if(n == 1) return lists[0];
ListNode *p = lists[0];
for(int i = 1; i < n; i++) {
p = mergeTwoList(p, lists[i]);
}
return p;
}
ListNode* mergeTwoList(ListNode* p1, ListNode* p2) {
ListNode *dummy = new ListNode(-1);
dummy->next = p1;
ListNode *cur = dummy;
while(p1 && p2) {
if(p1->val < p2->val) {
cur->next = p1;
p1 = p1->next;
} else {
cur->next = p2;
p2 = p2->next;
}
cur = cur->next;
}
if(p1) cur->next = p1;
if(p2) cur->next = p2;
return dummy->next;
}
};
2. 解法二
解题思路:
- 假设共有n个单链表需要合并
- 如果n为奇数,例如5
- 第一轮:将第一个和第四个合并(合并结果保存在第一个),第二个和第五个合并(合并结果保存在第二个),第三个保持不变
- 第二轮:将第一个和第三个合并,第二个保持不变;
- 第三轮:将第一个和第二个合并,算法结束;
- 假设n为偶数,例如6
- 第一轮:第一个和第四个合并,第二个和第五个合并,第三个和第六个合并;
- 第二轮:第一个和第三个合并,第二个保持不变;
- 第三轮:第一个和第二个合并,算法结束
- 如果n为奇数,例如5
- 计算出合并链表距离: k = (n + 1) / 2,第i个和第(i+k)个合并;
- 代码如下(合并两个有序链表的代码同解法一)
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
if(n == 0) return nullptr;
while(n > 1) {
int k = (n + 1) / 2;
for(int i = 0; i < n/2; i++) {
lists[i] = mergeTwoList(lists[i], lists[i+k]);
}
n = k;
}
return lists[0];
}
ListNode* mergeTwoList(ListNode* p1, ListNode* p2) {
ListNode *dummy = new ListNode(-1);
dummy->next = p1;
ListNode *cur = dummy;
while(p1 && p2) {
if(p1->val < p2->val) {
cur->next = p1;
p1 = p1->next;
} else {
cur->next = p2;
p2 = p2->next;
}
cur = cur->next;
}
if(p1) cur->next = p1;
if(p2) cur->next = p2;
return dummy->next;
}
};
参考: