LeetCode 23 Merge k Sorted Lists (C,C++,Java,Python)

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
时间: 2024-10-09 12:39:17

LeetCode 23 Merge k Sorted Lists (C,C++,Java,Python)的相关文章

[LeetCode]23. Merge k Sorted Lists

23. Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 给定k个排序了的链表,合并k个链表成一个排序链表. 本程序思路: 1)首先得到K个链表的长度和存在len中 2)从K个链表中找到值最小的那个节点,把该节点添加到合并链表中 3)重复len次即可把所有节点添加到合并链表中. 注意事项: 1)K个链表中有的

[LeetCode] 23. Merge k Sorted Lists 合并k个有序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 与21. Merge Two Sorted Lists的拓展,这道题要合并k个有序链表,还是可以两两合并. 类似题目: [LeetCode] 21. Merge Two Sorted Lists 合并有序链表 原文地址:https://www.cnblogs.com/lightwindy/p/8512

leetCode 23. Merge k Sorted Lists (合并k个排序链表) 解题思路和方法

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:此题是由合并两个排序链表演化而来,刚开始,想法比较简单,像求最大公共前缀一样,逐一求解:但是最后超时,所以马上意识到出题方是为了使用归并和分治的方法,故重新写了代码. 代码一(超时未过): /** * Definition for singly-link

[LeetCode] 23. Merge k Sorted Lists ☆☆

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解法1: 采用递归的方法,不管合并几个,归根到底还是需要两两合并. 首先想到的是前两个先合并,然后再跟第三个合并,然后第四个....但是这种做法效率不高. 换个思路,采用分治法,对数量超过2的任务进行拆分,直到最后只有一个或两个链表再进行合并.代码如下: /** * Definition for si

LeetCode #23 Merge k Sorted Lists (H)

[Problem] Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. [Analysis] 这题一上来,就会想到之前做过的Merge Two Sorted Lists.但是如果单纯地不断将新的list merge进结果,复杂度是非常高的,因为仔细想想就会发现在这个过程中结果里已经merge过的元素需要被重新排序,而这一部分无用功是可以通过使用合理的技

leetcode 23. Merge k Sorted Lists(堆||分治法)

Merge k sorted linked lists and return it as one sorted list. 题意:把k个已经排好序的链表整合到一个链表中,并且这个链表是排了序的. 题解:这是一道经典好题,值得仔细一说. 有两种方法,假设每个链表的平均长度是n,那么这两种方法的时间复杂度都是O(nklogk). 方法一: 基本思路是:把k个链表开头的值排个序,每次取最小的一个值放到答案链表中,这次取完之后更新这个值为它后面的一个值.接着这么取一直到全部取完.那么每次更新之后怎么对当

Java [leetcode 23]Merge k Sorted Lists

题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解题思路: 分而自治方法.将K个List不断地分解为前半部分和后半部分.分别进行两个List的合并.最后将合并的结果合并起来. 代码如下: /** * Definition for singly-linked list. * public class ListNode { * int va

[LeetCode]23. Merge k Sorted Lists合并K个排序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Example: Input: [   1->4->5,   1->3->4,   2->6 ] Output: 1->1->2->3->4->4->5->6 要合并K个排好序的链表,我用的方法是用一个优先队列每次存K个元素在队列中,根据优

LeetCode 21 Merge Two Sorted Lists (C,C++,Java,Python)

Problem: Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. Solution: 两个有序链表,每次取头部最小的那个元素,然后将这个元素从原来链表中去掉,依次循环 题目大意: 给定两个有序链表,要求将链表合并为一个有序链表,并且不能使用额外的空间 Java源代