【题目】
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
【分析】
无
【代码】
/*********************************
* 日期:2015-01-06
* 作者:SJF0115
* 题目: 23.Merge k Sorted Lists
* 来源:https://oj.leetcode.com/problems/merge-k-sorted-lists/
* 结果:Time Limit Exceeded
* 来源:LeetCode
* 博客:
**********************************/
#include <iostream>
#include <vector>
using namespace std;
struct ListNode{
int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
ListNode *head = NULL;
if(lists.size() == 0){
return head;
}//if
for(int i = 0;i < lists.size();i++){
head = mergeTwoLists(head,lists[i]);
}//for
return head;
}
private:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
if(l1 == NULL) return l2;
if(l2 == NULL) return l1;
if(l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l2->next, l1);
return l2;
}
}
};
// 创建链表
ListNode* CreateList(int A[],int n){
ListNode *head = NULL;
if(n <= 0){
return head;
}//if
head = new ListNode(A[0]);
ListNode *p1 = head;
for(int i = 1;i < n;i++){
ListNode *node = new ListNode(A[i]);
p1->next = node;
p1 = node;
}//for
return head;
}
int main() {
Solution solution;
vector<ListNode*> vecs;
int A[] = {1,2,4,7,9};
int B[] = {3,5,8,10,11,12};
int C[] = {6,10,13};
int D[] = {15,16,17,23};
ListNode* head1 = CreateList(A,5);
ListNode* head2 = CreateList(B,6);
ListNode* head3 = CreateList(C,3);
ListNode* head4 = CreateList(D,4);
vecs.push_back(head1);
vecs.push_back(head2);
vecs.push_back(head3);
vecs.push_back(head4);
ListNode *head = solution.mergeKLists(vecs);
// 输出
ListNode *p = head;
while(p){
cout<<p->val<<" ";
p = p->next;
}//while
cout<<endl;
}
这种方法超时。。。。。。。
【分析二】
采用最小优先级队列。
第一步:把非空的链表装进最小优先级队列中。
第二步:遍历最小优先级队列,直到最小优先级队列空为止。每次遍历,都能从最小优先级队列中取出具有当前最小的元素的链表。
如果除最小元素之外,链表不空,重新装进最小优先级队列中。
【代码二】
/*********************************
* 日期:2015-01-06
* 作者:SJF0115
* 题目: 23.Merge k Sorted Lists
* 来源:https://oj.leetcode.com/problems/merge-k-sorted-lists/
* 结果:AC
* 来源:LeetCode
* 博客:
**********************************/
#include <iostream>
#include <queue>
using namespace std;
struct ListNode{
int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
ListNode *head = new ListNode(-1);
ListNode *p = head;
// 最小优先级队列
priority_queue<ListNode*,vector<ListNode*>,cmp> Heap;
// 链表加入优先级队列
for(int i = 0;i < lists.size();i++){
if(lists[i] != NULL){
Heap.push(lists[i]);
}//if
}//for
// merge
while(!Heap.empty()){
// 最小的
ListNode *list = Heap.top();
Heap.pop();
p->next = list;
p = list;
if(list->next != NULL){
Heap.push(list->next);
}//if
}//while
return head->next;
}
private:
// 用于最小优先级队列
struct cmp {
bool operator()(ListNode* node1, ListNode* node2) {
return node1->val > node2->val;
}//bool
};
};
// 创建链表
ListNode* CreateList(int A[],int n){
ListNode *head = NULL;
if(n <= 0){
return head;
}//if
head = new ListNode(A[0]);
ListNode *p1 = head;
for(int i = 1;i < n;i++){
ListNode *node = new ListNode(A[i]);
p1->next = node;
p1 = node;
}//for
return head;
}
int main() {
Solution solution;
vector<ListNode*> vecs;
int A[] = {1,2,4,7,9};
int B[] = {3,5,8,10,11,12};
int C[] = {6,10,13};
int D[] = {15,16,17,23};
ListNode* head1 = CreateList(A,5);
ListNode* head2 = CreateList(B,6);
ListNode* head3 = CreateList(C,3);
ListNode* head4 = CreateList(D,4);
vecs.push_back(head1);
vecs.push_back(head2);
vecs.push_back(head3);
vecs.push_back(head4);
ListNode *head = solution.mergeKLists(vecs);
// 输出
ListNode *p = head;
while(p){
cout<<p->val<<" ";
p = p->next;
}//while
cout<<endl;
}
【分析三】
I think my code's complexity is also O(nlogk) and not using heap or priority queue, n means the total elements and k means the size of list.
The mergeTwoLists functiony in my code comes from the problem Merge Two Sorted Listswhose complexity obviously is O(n), n is the sum of length of l1 and l2.
To put it simpler, assume the k is 2^x, So the progress of combination is like a full binary tree, from bottom to top. So on every level of tree, the combination complexity is n, beacause every level have all n numbers without repetition. The level of tree is x, ie logk. So the complexity isO(nlogk).
for example, 8 ListNode, and the length of every ListNode is x1, x2, x3, x4, x5, x6, x7, x8, total is n.
on level 3: x1+x2, x3+x4, x5+x6, x7+x8 sum: n
on level 2: x1+x2+x3+x4, x5+x6+x7+x8 sum: n
on level 1: x1+x2+x3+x4+x5+x6+x7+x8 sum: n
total 3n, nlog8
【代码三】
/*********************************
* 日期:2015-01-07
* 作者:SJF0115
* 题目: 23.Merge k Sorted Lists
* 来源:https://oj.leetcode.com/problems/merge-k-sorted-lists/
* 结果:AC
* 来源:LeetCode
* 博客:
**********************************/
#include <iostream>
#include <limits.h>
#include <queue>
using namespace std;
struct ListNode{
int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
int count = lists.size();
if(count == 0){
return NULL;
}//if
if(count == 1){
return lists[0];
}//if
// 链表集合分成两份
vector<ListNode *> leftLists;
for(int i = 0;i < count/2;i++){
leftLists.push_back(lists.back());
lists.pop_back();
}//for
// 分治
return mergeTwoLists(mergeKLists(leftLists),mergeKLists(lists));
}
private:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode *head = new ListNode(-1);
for(ListNode *p = head;l1 != NULL || l2 != NULL;p = p->next){
int val1 = (l1 == NULL) ? INT_MAX : l1->val;
int val2 = (l2 == NULL) ? INT_MAX : l2->val;
if(val1 <= val2){
p->next = l1;
l1 = l1->next;
}//if
else{
p->next = l2;
l2 = l2->next;
}//else
}//for
return head->next;
}
};
// 创建链表
ListNode* CreateList(int A[],int n){
ListNode *head = NULL;
if(n <= 0){
return head;
}//if
head = new ListNode(A[0]);
ListNode *p1 = head;
for(int i = 1;i < n;i++){
ListNode *node = new ListNode(A[i]);
p1->next = node;
p1 = node;
}//for
return head;
}
int main() {
Solution solution;
vector<ListNode*> vecs;
int A[] = {1,2,4,7,9};
int B[] = {3,5,8,10,11,12};
int C[] = {6,10,13};
int D[] = {15,16,17,23};
ListNode* head1 = CreateList(A,5);
ListNode* head2 = CreateList(B,6);
ListNode* head3 = CreateList(C,3);
ListNode* head4 = CreateList(D,4);
vecs.push_back(head1);
vecs.push_back(head2);
vecs.push_back(head3);
vecs.push_back(head4);
ListNode *head = solution.mergeKLists(vecs);
// 输出
ListNode *p = head;
while(p){
cout<<p->val<<" ";
p = p->next;
}//while
cout<<endl;
}