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

示例:

输入:

[

1->4->5,

1->3->4,

2->6

]

输出: 1->1->2->3->4->4->5->6

1.不使用递归

基本思路:我们可以使用分治思想 来解决这个问题。当一个链表集合中需要合并并排序。我们可以假设只有2个 每次合并两个。两个合并一个。这样就可以获取到最终的结果。

第一次将list[0]与list[len-1]合并 2次list[1]与list[len-2] 经过 for循环一次后。可以等到一半的list链表结合。在依次len = len/2; 依次合并 就可以获取到下标为0的为头结点的这个链表。

//合并两个有序的链表
    public ListNode mergeKLists(ListNode[] lists) {
        int len = lists.length;
        if (len == 0)
            return null;
        while (len > 1) {
            for (int i = 0; i < len / 2; i++) {
                lists[i] = merageKList(lists[i],lists[len-1-i]);
            }
            len = (len+1)/2;
        }
        return lists[0];
    }

    //合并两个有序的链表 
    private ListNode merageKList(ListNode l1, ListNode l2) {
        if (l1 == null)
            return null;
        if (l2 == null)
            return null;

        ListNode listNode = new ListNode(-1);
        ListNode head = listNode;

        while (l1 != null && l2 != null) {
            if (l1.data < l2.data) {
                head.next = l1;
                l1 = l1.next;
            } else {
                head.next = l2;
                l2 = l2.next;
            }
            head = head.next;
        }

        if (l1 != null){
            head.next = l1;
        }else{
            head.next = l2;
        }
        return listNode.next; //note 注意返回的不是head 返回head 会带有 -1这个结点的值 只需要后边的值 牛掰思想
    }

时间复杂度:整体时间复杂度为O(N*log(k)), k为链表个数,N为链表平均长度。