Problem:
Merge
k
sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Solution:
采用胜者树的方法,胜者树介绍:胜者树,假如链表数组长度为n,链表元素总个数为k,那么时间复杂度为O(k*log(n))
题目大意:
给定一个数组有序链表(数组元素可能为空),要求将这些链表合并为一个有序的链表。
Java源代码(522ms):
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
private int[] tree;
public ListNode mergeKLists(ListNode[] lists) {
int len=lists.length;
if(len==0)return null;
else if(len==1)return lists[0];
tree=new int[len];
initTree(lists,len);
if(lists[tree[1]]==null)return null;
ListNode p,head;
p=lists[tree[1]];
lists[tree[1]]=lists[tree[1]].next;
head=p;
adjustToRoot(lists,(tree[1]+len)/2,len);
while(lists[tree[1]]!=null){
p.next=lists[tree[1]];
lists[tree[1]]=lists[tree[1]].next;
p=p.next;
adjustToRoot(lists,(tree[1]+len)/2,len);
}
return head;
}
private void adjustToRoot(ListNode[] lists,int tar,int len){
while(tar>0){
adjustTree(lists,tar,len);
tar=tar/2;
}
}
private void initTree(ListNode[] lists,int len){
for(int i=len-1;i>=1;i--){
adjustTree(lists,i,len);
}
}
private void adjustTree(ListNode[] lists,int i,int len){
int l,r;
if(i+i < len){
l=tree[i+i];
}else{
l=i+i-len;
}
if(i+i+1 < len){
r=tree[i+i+1];
}else{
r=i+i+1-len;
}
if(lists[l]==null)tree[i]=r;
else if(lists[r]==null)tree[i]=l;
else tree[i]= lists[l].val > lists[r].val ? r:l;
}
}
C语言源代码(389ms):
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
void adjustTree(struct ListNode** lists,int i,int length,int* tree){
int l,r;
if(i*2 < length){
l=tree[i*2];
}else{
l=i*2-length;
}
if(i*2+1 < length){
r=tree[i*2+1];
}else{
r=i*2-length+1;
}
if(lists[l]==NULL)tree[i]=r;
else if(lists[r]==NULL)tree[i]=l;
else tree[i]= lists[l]->val > lists[r]->val ?r:l;
}
void buildWinnerTree(struct ListNode** lists,int length,int* tree){
int i;
for(i=length-1;i>=1;i--){
adjustTree(lists,i,length,tree);
}
}
void adjustToRoot(struct ListNode** lists,int tar,int length,int* tree){
while(tar>0){
adjustTree(lists,tar,length,tree);
tar=tar/2;
}
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
struct ListNode *p,*head;
int* tree=(int*)malloc(sizeof(int)*(listsSize));
if(listsSize==0)return NULL;
else if(listsSize==1)return lists[0];
buildWinnerTree(lists,listsSize,tree);
if(lists[tree[1]]==NULL)return NULL;
p=lists[tree[1]];lists[tree[1]]=lists[tree[1]]->next;
head=p;
adjustToRoot(lists,(tree[1]+listsSize)/2,listsSize,tree);
while(lists[tree[1]]!=NULL){
p->next=lists[tree[1]];
lists[tree[1]]=lists[tree[1]]->next;
p=p->next;
adjustToRoot(lists,(tree[1]+listsSize)/2,listsSize,tree);
}
return head;
}
C++源代码(419ms):
/**
* 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) {
int len=lists.size();
if(len==0)return NULL;
else if(len==1)return lists[0];
WinnerTree=(int*)malloc(sizeof(int)*len);
initTree(lists,len);
if(lists[WinnerTree[1]]==NULL)return NULL;
ListNode *p,*head;
p=lists[WinnerTree[1]];
lists[WinnerTree[1]]=lists[WinnerTree[1]]->next;
head=p;
adjustToRoot(lists,(WinnerTree[1]+len)/2,len);
while(lists[WinnerTree[1]]!=NULL){
p->next=lists[WinnerTree[1]];
lists[WinnerTree[1]]=lists[WinnerTree[1]]->next;
p=p->next;
adjustToRoot(lists,(WinnerTree[1]+len)/2,len);
}
return head;
}
private:
int *WinnerTree;
void initTree(vector<ListNode*>& lists,int len){
for(int i=len-1;i>=1;i--){
adjustWinnerTree(lists,i,len);
}
}
void adjustToRoot(vector<ListNode*>& lists,int tar,int len){
while(tar>0){
adjustWinnerTree(lists,tar,len);
tar=tar/2;
}
}
void adjustWinnerTree(vector<ListNode*>& lists,int i,int len){
int l,r;
if(i+i < len){
l=WinnerTree[i+i];
}else{
l=i+i-len;
}
if(i+i+1 < len){
r=WinnerTree[i+i+1];
}else{
r=i+i+1-len;
}
if(lists[l]==NULL)WinnerTree[i]=r;
else if(lists[r]==NULL)WinnerTree[i]=l;
else WinnerTree[i]= lists[l]->val > lists[r]->val ?r:l;
}
};
Python源代码(618ms):
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
tree=[]
# @param {ListNode[]} lists
# @return {ListNode}
def mergeKLists(self, lists):
length=len(lists)
if length==0:return None
elif length==1:return lists[0]
self.tree=[0 for i in range(length)]
self.initTree(lists,length)
if lists[self.tree[1]]==None:return None
p=lists[self.tree[1]]
lists[self.tree[1]]=lists[self.tree[1]].next
head=p
self.adjustToRoot(lists,(self.tree[1]+length)/2,length)
while lists[self.tree[1]]!=None:
p.next=lists[self.tree[1]]
lists[self.tree[1]]=lists[self.tree[1]].next
p=p.next
self.adjustToRoot(lists,(self.tree[1]+length)/2,length)
return head
def adjustToRoot(self,lists,tar,length):
while tar>0:
self.adjustTree(lists,tar,length)
tar=tar/2
def initTree(self,lists,length):
for i in range(length-1,0,-1):
self.adjustTree(lists,i,length)
def adjustTree(self,lists,i,length):
l=0;r=0
if i+i < length:l=self.tree[i+i]
else:l=i+i-length
if i+i+1 < length:r=self.tree[i+i+1]
else:r=i+i+1-length
if lists[l]==None:self.tree[i]=r
elif lists[r]==None:self.tree[i]=l
else:self.tree[i]=r if lists[l].val > lists[r].val else l