(LeetCode)23. 合并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
示例 2:

输入:lists = [] 输出:[] 示例 3:

输入:lists = [[]] 输出:[]

提示:

k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-104 <= lists[i][j] <= 104
lists[i] 按 升序 排列
lists[i].length 的总和不超过 104

(简单暴力)两两合并

	public ListNode mergeKLists(ListNode[] lists) {
     
        if(lists.length == 0){
     
            return null;
        }
        for(int i = 1;i < lists.length;i++){
     
            lists[0] = sort(lists[0],lists[i]);
        }
        return lists[0];
    }
i.非递归合并(链表无头指针)
	public ListNode sort(ListNode list1,ListNode list2){
     
        ListNode q;
        if(list1!=null && list2!=null){
     
            if(list1.val <= list2.val){
     
                q = list1;
                list1 = list1.next;
            }else{
     
                q = list2;
                list2 = list2.next;
            }
        }else if(list1==null && list2==null){
     
            return null;
        }else{
     
            return list1!=null?list1:list2;
        }
        ListNode h = q;
        while(list1!=null && list2!=null){
     
            if(list1.val <= list2.val){
     
                q.next = list1;
                list1 = list1.next;
            }else{
     
                q.next = list2;
                list2 = list2.next;
            }
            q = q.next;
        }
        if(list1 != null){
     
            q.next = list1;
        }else{
     
            q.next = list2;
        }
        return h;
    }
i.非递归合并(链表有头指针)

(看的大佬的思路之后发现可以使用头指针,然后改了一下上面的代码,果然好看多了QAQ

public ListNode sort(ListNode list1,ListNode list2){
     
        ListNode q = new ListNode();
        ListNode h = q;
        while(list1!=null && list2!=null){
     
            if(list1.val <= list2.val){
     
                q.next = list1;
                list1 = list1.next;
            }else{
     
                q.next = list2;
                list2 = list2.next;
            }
            q = q.next;
        }
        if(list1 != null){
     
            q.next = list1;
        }else{
     
            q.next = list2;
        }
        return h.next;
    }
iii.递归合并

(代码确实简洁,但是运行时间长了一倍还多

	public ListNode sort(ListNode p1,ListNode p2){
     
        if(p1==null){
     
            return p2;
        }
        if(p2==null){
     
            return p1;
        }
        if(p1.val<=p2.val){
     
            p1.next = sort(p1.next,p2);
            return p1;
        }else{
     
            p2.next = sort(p1,p2.next);
            return p2;
        }
    }

K 指针:K 个指针分别指向 K 条链表

(这是大佬的代码
一开始自己想到的循环条件太差于是便舍弃了这一种方法……来借鉴一下大佬的算法orz

	public ListNode mergeKLists(ListNode[] lists) {
      
        int k = lists.length;
        ListNode dummyHead = new ListNode(0);
        ListNode tail = dummyHead;
        while (true) {
     
            ListNode minNode = null;
            int minPointer = -1;
            for (int i = 0; i < k; i++) {
     
                if (lists[i] == null) {
     
                    continue;
                }
                if (minNode == null || lists[i].val < minNode.val) {
     
                    minNode = lists[i];
                    minPointer = i;
                }
            }
            if (minPointer == -1) {
     
                break;
            }
            tail.next = minNode;
            tail = tail.next;
            lists[minPointer] = lists[minPointer].next;
        }
        return dummyHead.next;
    }

优先队列

(也是看的大佬的解题思路
学了优先队列之后都没有用过……

确实比上面几种方法快太多太多

	public ListNode mergeKLists(ListNode[] lists) {
     
        if(lists == null || lists.length == 0){
     
            return null;
        }
        PriorityQueue<ListNode> queue = new PriorityQueue<>(lists.length, new Comparator<ListNode>() {
     
            @Override
            public int compare(ListNode o1, ListNode o2) {
     
                if(o1.val < o2.val){
     
                    return -1;
                }else if(o1.val == o2.val){
     
                    return 0;
                }else{
     
                    return 1;
                }
            }
        });
        ListNode h = new ListNode();
        ListNode p = h;
        for(ListNode list : lists){
     
            if(list != null){
     
                queue.add(list);
            }
        }
        while(!queue.isEmpty()){
     
            p.next = queue.poll();
            p = p.next;
            if(p.next!=null){
     
                queue.add(p.next);
            }
        }
        return h.next;
    }

你可能感兴趣的:(java练习,leetcode,算法,队列,链表)