合并k个升序链表

合并K个升序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

//方式一:分别比较k个链表
public ListNode mergeKLists(ListNode[] lists) {
    int len = lists.length;
    ListNode result = new ListNode(-1);
    ListNode dummy = result;
    while(true){
        ListNode temp = null;
        int flag = -1;
        for(int i = 0;i<len;i++){
            if(lists[i] == null) continue;
            if(temp == null || lists[i].val < temp.val){
                temp = lists[i];
                flag = i;
            }
        }
        if(flag == -1) break;
        dummy.next = temp;
        dummy = dummy.next;
        lists[flag] = lists[flag].next;
    }
    return result.next;
}    
//方式二:对上一种方法优化,使用小根堆对 1 进行优化,每次 O(logK)O(logK) 比较 K个指针求 min, 时间复杂度:O(NlogK)   O(NlogK)
public ListNode mergeKLists(ListNode[] lists) {
    Queue<ListNode> queue = new PriorityQueue<ListNode>((n1,n2)->n1.val - n2.val);
    for(ListNode temp:lists){
        if(temp != null){
            queue.offer(temp);
        }
    }
    ListNode result = new ListNode(-1);
    ListNode dummy = result;
    while(!queue.isEmpty()){
        ListNode node = queue.poll();
        dummy.next = node;
        dummy = dummy.next;
        if(node.next != null){
            queue.offer(node.next);
        }
    }
    return result.next;
}
//方式三:两两合并 - 迭代
public ListNode mergeKLists(ListNode[] lists) {
    if(lists.length == 0) return null;
    int len = lists.length;
    while(len > 1){
        int temp = 0;
        for(int i = 0;i<len;i += 2){
            if(i == len -1){
                lists[temp++] = lists[i];
            }else{
                lists[temp++] = merge2Lists(lists[i],lists[i+1]);
            }
        }
        len = temp;
    }
    return lists[0];
}
//两两合并的子方法
public ListNode merge2Lists(ListNode l1,ListNode l2){
    ListNode result = new ListNode(-1);
    ListNode dummy = result;
    while(l1 != null && l2 != null){
        if(l1.val < l2.val){
            dummy.next = l1;
            l1 = l1.next;
        }else{
            dummy.next = l2;
            l2 = l2.next;
        }
        dummy = dummy.next;
    }
    dummy.next = l1 == null?l2:l1;
    return result.next;
}
//方式四:两两合并 - 递归
public ListNode mergeKLists(ListNode[] lists) {
    if(lists.length == 0) return null;
    return merge(lists,0,lists.length-1);
}

public ListNode merge(ListNode[] lists,int left,int right){
    if(left == right) return lists[left];
    int mid = (left + right) /2;
    ListNode l1 = merge(lists,left,mid);
    ListNode l2 = merge(lists,mid+1,right);
    return merge2Lists(l1,l2);
}

public ListNode merge2Lists(ListNode l1,ListNode l2){
    if(l1 == null) return l2;
    if(l2 == null) return l1;
    if(l1.val < l2.val){
        l1.next = merge2Lists(l1.next,l2);
        return l1;
    }
    l2.next = merge2Lists(l1,l2.next);
    return l2;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 点我我会动 设计师:上身试试 返回首页