图解算法——合并k个排序列表(Merge k Sorted Lists)

1. 题目描述

You are given an array of k linked-lists lists, each linked-list is sorted in ascending order.
Merge all the linked-lists into one sorted linked-list and return it.

翻译:

给定一个链表长度为k的链表数组,每个链表按升序排序。

将数组中所有的链表合并为一个有序的链表,并返回它。

2.示例

示例1:

Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
  1->4->5,
  1->3->4,
  2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6

示例2:

Input: lists = []
Output: []

示例3:

Input: lists = [[]]
Output: []

3.要求

  • k == lists.length

  • 0 <= k <= 10^4

  • 0 <= lists[i].length <= 500

  • -10^4 <= lists[i][j] <= 10^4

  • lists[i] is sorted in ascending order.

  • The sum of lists[i].length won't exceed 10^4.

4. 题目解析

其实,这个题目和归并排序有相似之处。归并排序是一个数组(也可以看做是两个数组哈)的排序,而这个题目是多个;

归并排序中原数组不一定是有序的,而这里的数组都是按照升序排列的。

合并k个有序list,有递归和非递归两种解法,

思路:递归:

就是先新建一个链表,然后用该链表和整个链表数组中的每一个链表进行两两结合。

*/
/*
 * 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==null || lists.length<=0
            || lists[0]==null || lists[0].length<=0){
            return null;
        }
        
        ListNode head = null;//新建的链表头结点
        for(int i = 0; i<lists.length;i++){
            ListNode listnode = lists[i];  //取出数组中的每一个链表
            head = merge2Link(head,listnode);//合并
        }
        return head;
    }
    
    public ListNode merge2Link(ListNode head, ListNode tail){
        if(tail == null)
            return head;
        if(head == null)
            return tail;
        
        if(head.val < tail.val){
            head.next = merge2Link(head.next,tail);//递归
            return head;
        }else{
            tail.next = merge2Link(head,tail.next);//递归
            return tail;
        }
    }
}

非递归思路:

和上述思路一致,都是两两合并,只不过重写了merge2Link()方法,不是递归的思路,如下:

    /*
    接下来就用到归并排序思想了
    */
    public ListNode merge2Link(ListNode node1, ListNode node2){
        ListNode res = new ListNode(0);//返回时,将res.next返回 
        ListNode head = res;//中间指针变量,下面的循环用到的是这个指针
        while(node1!=null && node2!=null){
            if(node1.val<node2.val){
                head.next = node1;
                node1 = node1.next;
            }else{
                head.next = node2;
                node2 = node2.next;
            }
            head = head.next;
        }
        while(node1!=null){
            head.next = node1;
        }
        while(node2!=null){
            head.next = node2;
        }
        return res.next;
    }

Over......

原文地址:https://www.cnblogs.com/gjmhome/p/14406726.html