23. Merge k Sorted Lists

作者: DrunkPian0 | 来源:发表于2017-03-27 22:03 被阅读55次

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

    31/05/2017
    今天又看了一下这个题,重温了一下PriorityQueue。
    这题思路:
    每次把PriorityQueue里最小的那个Node撸下来,然后把这个最小Node的next结点加入到PriorityQueue里去。PriorityQueue的意义在于能保证队首永远是最小的Node,后面的顺序每次add/offer都会变,无法保证是按顺序的(堆排序我还需要再复习一遍),但是我们也不需要后面是按顺序的,只需要min heap的堆顶元素就行了。


    这题用了堆heap的思想,用的是优先权队列实现的。

       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) {
                    //none - descending sort
                    return o1.val - o2.val;
                }
            });
    
            for (ListNode list : lists) {
                if (list != null)
                    queue.offer(list);
            }
    
            ListNode dummy = new ListNode(-1);
            ListNode tail = dummy;
            while (!queue.isEmpty()) {
                tail.next = queue.poll();
                tail = tail.next;
    
                //把每个链表上的node全撸下来加入到queue,注意这个撸下来的过程可能不是连续的,可能先撸了第一个链表的next就去撸下一个链表了
                if (tail.next != null) {
                    queue.offer(tail.next);
                }
            }
            return dummy.next;
        }
    
    

    一开始我不懂为什么这题的参数是一个数组,我以为应该是好几个参数,每个参数是一个list呢。直到看到

                if (tail.next != null) {
                    queue.offer(tail.next);
                }
    

    我才恍然大悟,每个listNode自身就是一个链表呀。

    引用CodeGanker的讲解:

    维护一个大小为k的堆,每次取堆顶的最小元素放到结果中,然后读取该元素的下一个元素放入堆中,重新维护好。因为每个链表是有序的,每次又是去当前k个元素中最小的,所以当所有链表都读完时结束,这个时候所有元素按从小到大放在结果链表中。

    其实我有点不太懂为什么这k个list要是已经排序好的了,因为这样看来根本不需要啊(我不懂Java的PriorityQueue是不是每次add/offer一个元素就会自动排序一次?如果是的话,那无论怎么插入元素,poll出来的永远是排好序的queue中的最小元素呀。。)

    对于复杂度:这个算法每个元素要读取一次,即是k*n次,然后每次读取元素要把新元素插入堆中要logk的复杂度,所以总时间复杂度是O(nklogk)。空间复杂度是堆的大小,即为O(k)。

    看来这里的offer/add用的是二分搜索形式。

    相关文章

      网友评论

        本文标题:23. Merge k Sorted Lists

        本文链接:https://www.haomeiwen.com/subject/fekdottx.html