23. 合并K个升序链表

递归

class Solution {

    public ListNode mergeKLists(ListNode[] lists){

        return mergeKLists(lists, 0);
    }

    public ListNode mergeKLists(ListNode[] lists, int left){

        if (left >= lists.length){
            return null;
        }

        if (left == lists.length - 1){
            return lists[left];
        }

        /**
         * 递归
         * 假设lists[1, length - 1]的链表已经排好序,且返回头节点list
         * 最后只用让lists[0]合并进最终的链表
         */
        ListNode list = mergeKLists(lists, left + 1);

        /**
         * 定义最终链表的虚拟头节点
         * 然后依次拿出两个链表的元素比较,始终指向较小的那个节点
         */
        ListNode dummyHead = new ListNode();
        ListNode prev = dummyHead;
        ListNode cur = lists[left];

        while (cur != null && list != null){

            if (cur.val < list.val){

                prev.next = cur;
                cur = cur.next;
            }
            else {

                prev.next = list;
                list = list.next;
            }

            prev = prev.next;
        }

        /**
         * 一旦有一个链表空了,直接指向剩余的链表
         */
        prev.next = cur == null ? list : cur;

        return dummyHead.next;
    }
}

/**
 * 时间复杂度 O(nlogn)
 * 空间复杂度 O(n)
 */

优先队列

class Solution {

    public ListNode mergeKLists(ListNode[] lists){

        ListNode dummyHead = new ListNode();
        ListNode prev = dummyHead;

        PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val - o2.val;
            }
        });

        /**
         * 将每个子链表的头节点放进队列
         * 按照节点的大小升序排列
         */
        for (int i = 0; i < lists.length; i++) {

            if (lists[i] != null) {
                pq.add(lists[i]);
            }
        }

        /**
         * 然后每次让最小的节点出队,作为总链表的下一个节点,然后将其下一个节点入队,继续比较
         */
        while (!pq.isEmpty()){

            ListNode temp = pq.poll();
            
            prev.next = temp;
            prev = prev.next;
            temp = temp.next;

            if (temp != null) {
                pq.add(temp);
            }
        }

        return dummyHead.next;
    }
}

/**
 * 时间复杂度 O(nlogn)
 * 空间复杂度 O(k)
 */

https://leetcode-cn.com/problems/merge-k-sorted-lists/

posted @ 2021-12-24 16:42  振袖秋枫问红叶  阅读(29)  评论(0)    收藏  举报