题目:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
题解:
采用Heap的方法,C++和Java用Priority Queue + customized comparator实现最小堆,Python直接使用heapq, heapq.heappush, heapq.heappop。算法复杂度,每加入一个元素进堆,需要O(lgk)时间,k为lists中list的个数。共有nk个元素,所以总共需要O(nklgk)时间加入全部元素,其中n为每个list的元素个数的最大值。每次取最小值为O(1)时间复杂度,所以总共为O(nklgk)时间复杂度。
c++版:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
struct comparator {
bool operator() (ListNode* i, ListNode* j) {
return i->val > j->val;
}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(!lists.size())
return NULL;
ListNode* dummyHead = new ListNode(0);
ListNode* pointer = dummyHead;
priority_queue<ListNode*, vector<ListNode*>, comparator> heap;
for(int i = 0; i < lists.size(); i++) {
heap.push(lists[i]);
}
while(heap.size()) {
ListNode* temp = heap.top();
heap.pop();
pointer->next = temp;
pointer = pointer->next;
if(temp->next)
heap.push(temp->next);
}
return dummyHead->next;
}
};
int main(int argc, char** argv) {
ListNode* h1 = new ListNode(3);
ListNode* h2 = new ListNode(2);
ListNode* h3 = new ListNode(1);
ListNode* n12 = new ListNode(5);
ListNode* n13 = new ListNode(7);
ListNode* n14 = new ListNode(9);
ListNode* n22 = new ListNode(4);
ListNode* n23 = new ListNode(6);
ListNode* n24 = new ListNode(8);
ListNode* n32 = new ListNode(3);
ListNode* n33 = new ListNode(4);
ListNode* n34 = new ListNode(8);
h1->next = n12;
n12->next = n13;
n13->next = n14;
h2->next = n22;
n22->next = n23;
n23->next = n24;
h3->next = n32;
n32->next = n33;
n33->next = n34;
vector<ListNode*> input;
input.push_back(h1);
input.push_back(h2);
input.push_back(h3);
Solution s;
ListNode* result = s.mergeKLists(input);
while(result) {
cout << result->val << " ";
result = result->next;
}
cout << endl;
return 0;
}
Java版:
package leetcode;
import java.util.*;
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
class MyComparator implements Comparator<ListNode>{
public int compare(ListNode x, ListNode y) {
return x.val - y.val;
}
}
class Solution {
public ListNode mergeKLists(List<ListNode> lists) {
if(lists.size() == 0)
return null;
ListNode dummyHead = new ListNode(0);
PriorityQueue<ListNode> minHeap = new PriorityQueue<ListNode>(lists.size(), new MyComparator());
ListNode pointer = dummyHead;
for(int i = 0; i < lists.size(); i++) {
if(lists.get(i) != null)
minHeap.add(lists.get(i));
}
while(minHeap.size() != 0) {
ListNode temp = minHeap.poll();
pointer.next = temp;
if(temp.next != null)
minHeap.add(temp.next);
pointer = pointer.next;
}
return dummyHead.next;
}
}
public class Leetcode {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
ListNode h1 = new ListNode(1);
ListNode h2 = new ListNode(2);
ListNode h3 = new ListNode(1);
ListNode n12 = new ListNode(5);
ListNode n13 = new ListNode(7);
ListNode n14 = new ListNode(9);
ListNode n22 = new ListNode(4);
ListNode n23 = new ListNode(6);
ListNode n24 = new ListNode(8);
ListNode n32 = new ListNode(3);
ListNode n33 = new ListNode(4);
ListNode n34 = new ListNode(8);
h1.next = n12;
n12.next = n13;
n13.next = n14;
h2.next = n22;
n22.next = n23;
n23.next = n24;
h3.next = n32;
n32.next = n33;
n33.next = n34;
List<ListNode> input = new ArrayList<ListNode>();
input.add(h1);
input.add(h2);
input.add(h3);
Solution s = new Solution();
ListNode result = s.mergeKLists(input);
while(result != null) {
System.out.print(result.val);
System.out.print(" ");
result = result.next;
}
System.out.println();
}
}
Python版:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param a list of ListNode
# @return a ListNode
def mergeKLists(self, lists):
if len(lists) == 0:
return None
h = []
dummyHead = ListNode(0)
pointer = dummyHead
for i in range(0,len(lists)):
if lists[i] != None:
heapq.heappush(h, (lists[i].val, lists[i]))
while len(h) != 0:
temp = heapq.heappop(h)
pointer.next = temp[1]
if temp[1].next != None:
heapq.heappush(h, (temp[1].next.val, temp[1].next))
pointer = pointer.next
return dummyHead.next