LeetCode刷题笔记-23. 合并K个排序链表(分治法)

题目:
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
1->4->5,
1->3->4,
2->6
]
输出:
1->1->2->3->4->4->5->6

题解:
参考这题21. 合并两个有序链表。
①:将k个排序链表两两排序,排k-1次后最终结果就是合并后结果,时间复杂度: O(kN),其中 k 是链表的数目,总共有 N个节点在最后的链表中。空间复杂度:O(1)。代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        int n=lists.length;
        if(n==0||lists==null) return null;
        for(int i=0;i<n-1;i++){
            lists[i+1]=mergeTwoLists(lists[i],lists[i+1]);
        }
        return lists[n-1];
    }
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null) return l2;
        if(l2==null) return l1;
        ListNode l1_temp=new ListNode(0);
        ListNode l2_temp=new ListNode(0);
        ListNode result=new ListNode(0);
        l1_temp=l1;
        l2_temp=l2;
        while(true){
            if(l1_temp.val>=l2_temp.val){
                result.next=l2_temp;
                l2_temp=l2_temp.next;
            }
            else {
                result.next=l1_temp;
                l1_temp=l1_temp.next;
            }
            result=result.next;
            if(l1_temp==null) {
                result.next=l2_temp;
                break;
            }
            if(l2_temp==null){
                result.next=l1_temp;
                break;
            }
        }
            if(l1.val>=l2.val) return l2;
            else return l1;
    }
}

②:思考后发现其实有可以优化的地方,对k个数组合并可以采用分治法,防止合并时耗时过高:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        int n=lists.length;
        if(n==0||lists==null) return null;
        while(n>1){
            if(n%2==1) lists[n-2]=mergeTwoLists(lists[n-2],lists[n-1]);
            for(int i=0;i<n/2;i++){
                lists[i]=mergeTwoLists(lists[2*i],lists[2*i+1]);
            }
            n/=2;
        }
        return lists[0];
    }
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null) return l2;
        if(l2==null) return l1;
        ListNode l1_temp=new ListNode(0);
        ListNode l2_temp=new ListNode(0);
        ListNode result=new ListNode(0);
        l1_temp=l1;
        l2_temp=l2;
        while(true){
            if(l1_temp.val>=l2_temp.val){
                result.next=l2_temp;
                l2_temp=l2_temp.next;
            }
            else {
                result.next=l1_temp;
                l1_temp=l1_temp.next;
            }
            result=result.next;
            if(l1_temp==null) {
                result.next=l2_temp;
                break;
            }
            if(l2_temp==null){
                result.next=l1_temp;
                break;
            }
        }
            if(l1.val>=l2.val) return l2;
            else return l1;
    }
}

③:还有一种可以借鉴的递归分治法,但是由于递归会超时,所以只将代码分享出来,取其精华即可:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0||lists==null) return null;
        return recursion(lists,0,lists.length-1);
    }
    public ListNode recursion(ListNode[] lists,int left,int right){
        if(right==left) return lists[right];
        int mid=(right+left)/2;
        ListNode list1=new ListNode();
        ListNode list2=new ListNode();
        list1=recursion(lists,0,mid);
        list2=recursion(lists,mid+1,right);
        return mergeTwoLists(list1,list2);
    }
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null) return l2;
        if(l2==null) return l1;
        ListNode l1_temp=new ListNode(0);
        ListNode l2_temp=new ListNode(0);
        ListNode result=new ListNode(0);
        l1_temp=l1;
        l2_temp=l2;
        while(true){
            if(l1_temp.val>=l2_temp.val){
                result.next=l2_temp;
                l2_temp=l2_temp.next;
            }
            else {
                result.next=l1_temp;
                l1_temp=l1_temp.next;
            }
            result=result.next;
            if(l1_temp==null) {
                result.next=l2_temp;
                break;
            }
            if(l2_temp==null){
                result.next=l1_temp;
                break;
            }
        }
            if(l1.val>=l2.val) return l2;
            else return l1;
    }
}

大神题解

你可能感兴趣的:(LeetCode刷题笔记)