23. 合并K个升序链表


23. 合并K个升序链表

解题思路

其实最开始的思路是N个指针,每次放最小的进新链表,但是这样时间复杂度太高了!合并两个有序链表可以考虑这样做。所以我选择维护一个小顶堆,将所有的元素都加入小顶堆,然后再出来的时候就是按照升序的顺序了。

对应到代码的话,相当于我们需要准备一个「集合」,将所有链表的头结点放入「集合」,然后每次都从「集合」中挑出最小值,并将最小值的下一个节点添加进「集合」(如果有的话),循环这个过程,直到「集合」为空(说明所有节点都处理完,进过集合又从集合中出来)。
注意题目是有序链表,所以我们一开始只需要放入头节点来比较

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length==0) return null;//空链表直接返回
        PriorityQueue<ListNode> sHeap = new PriorityQueue<ListNode>((a, b) -> a.val - b.val);
               
        ListNode fake = new ListNode();
        ListNode cur = fake;//保留头结点作为信标
        for(ListNode node:lists){
            if(node!=null){
                sHeap.add(node);//加入最小堆
            }
        }
        while(!sHeap.isEmpty()){
            ListNode poll = sHeap.poll();
            cur.next = poll;
            cur=cur.next;

            // 将最小值的下一个节点添加进「集合」(如果有的话)
            if(poll.next!=null){

                sHeap.add(poll.next);//头节点放了,如果头节点还有下一个那就把下一个要放进小顶堆
            }
        }
        return fake.next;
    }
}

文章作者: fFee-ops
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 fFee-ops !
评论
  目录