題目描述(難度難)
合併 k 個排序鏈表,返回合併後的排序鏈表。請分析和描述算法的複雜度。
示例:
輸入:
[
1->4->5,
1->3->4,
2->6
]
輸出: 1->1->2->3->4->4->5->6
鏈接
https://leetcode-cn.com/problems/merge-k-sorted-lists/
思路
比較好的兩種思路
1、與合併兩個有序鏈表一樣,K個鏈表一起從頭往尾走,每次選取K個鏈表中指針指向位置的最小值,這個最小值使用優先隊列維護較爲合適。
2、鏈表之間兩兩合併,可複用兩個有序鏈表合併的代碼。
- 從第一個鏈表開始,依次合併後面的鏈表
- 分治,第一個鏈表和第二個鏈表合併,第三個和第四個合併,如此下去
顯然,分治算法是很不錯的,在這裏本文采用這種方法。
代碼
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.size() == 0){
return NULL;
}
if(lists.size() == 1){
return lists[0];
}
if(lists.size() > 1){
vector<ListNode*> liststemp;
if(lists.size()%2 == 0){
for(int i = 0; i < lists.size(); i+=2){
ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
liststemp.push_back(ans);
}
lists = liststemp;
return mergeKLists(lists);
}
else{
// 這裏是 i < lists.size()-1 有所懷疑沒有仔細確認導致浪費了一點時間查錯
for(int i = 0; i < lists.size()-1; i+=2){
ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
liststemp.push_back(ans);
}
liststemp.push_back(lists[lists.size()-1]);
lists = liststemp;
return mergeKLists(lists);
}
}
return NULL;
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* ans = NULL;
if(l1 == NULL && l2 == NULL){
return NULL;
}
else if(l1 == NULL){
return l2;
}
else if(l2 == NULL){
return l1;
}
else{
ListNode* t1 = l1;
ListNode* t2 = l2;
if(t1->val < t2->val){
ans = t1;
t1 = t1->next;
}
else{
ans = t2;
t2 = t2->next;
}
ListNode* tans = ans;
while(t1&&t2){
if(t1->val < t2->val){
tans->next = t1;
t1 = t1->next;
tans = tans->next;
}
else{
tans->next = t2;
t2 = t2->next;
tans = tans->next;
}
}
while(t1){
tans->next = t1;
t1 = t1->next;
tans = tans->next;
}
while(t2){
tans->next = t2;
t2 = t2->next;
tans = tans->next;
}
}
return ans;
}
};
debug代碼:
#include <bits/stdc++.h>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.size() == 0){
return NULL;
}
if(lists.size() == 1){
return lists[0];
}
if(lists.size() > 1){
vector<ListNode*> liststemp;
if(lists.size()%2 == 0){
for(int i = 0; i < lists.size(); i+=2){
ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
liststemp.push_back(ans);
}
lists = liststemp;
return mergeKLists(lists);
}
else{
for(int i = 0; i < lists.size()-1; i+=2){
ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
liststemp.push_back(ans);
}
liststemp.push_back(lists[lists.size()-1]);
lists = liststemp;
return mergeKLists(lists);
}
}
return NULL;
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* ans = NULL;
if(l1 == NULL && l2 == NULL){
return NULL;
}
else if(l1 == NULL){
return l2;
}
else if(l2 == NULL){
return l1;
}
else{
ListNode* t1 = l1;
ListNode* t2 = l2;
if(t1->val < t2->val){
ans = t1;
t1 = t1->next;
}
else{
ans = t2;
t2 = t2->next;
}
ListNode* tans = ans;
while(t1&&t2){
if(t1->val < t2->val){
tans->next = t1;
t1 = t1->next;
tans = tans->next;
}
else{
tans->next = t2;
t2 = t2->next;
tans = tans->next;
}
}
while(t1){
tans->next = t1;
t1 = t1->next;
tans = tans->next;
}
while(t2){
tans->next = t2;
t2 = t2->next;
tans = tans->next;
}
}
return ans;
}
};
int main()
{
Solution s;
ListNode* l11 = new ListNode(1);
ListNode* l12 = new ListNode(4);
ListNode* l13 = new ListNode(5);
l11->next = l12;
l12->next = l13;
while(l11){
cout << l11->val << endl;
l11 = l11->next;
}
ListNode* l21 = new ListNode(1);
ListNode* l22 = new ListNode(3);
ListNode* l23 = new ListNode(4);
l21->next = l22;
l22->next = l23;
ListNode* l31 = new ListNode(2);
ListNode* l32 = new ListNode(6);
l31->next = l32;
vector<ListNode*> test;
test.push_back(l11);
test.push_back(l21);
test.push_back(l31);
ListNode* ans = s.mergeKLists(test);
while(ans){
cout << ans->val << " ";
ans = ans->next;
}
return 0;
}