- 使用优先权队列
PriorityQueue
,将所有链表的头结点加入,每次poll
弹出最小的,然后再加入这个节点的下一个,以此类推,能将所有链表有序合并。
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists.length == 0){
return null;
}
PriorityQueue<ListNode> listNodes = new PriorityQueue<>(
lists.length , (o1,o2) -> o1.val - o2.val
);
for (ListNode listNode : lists) {
if (listNode != null) {
listNodes.add(listNode);
}
}
ListNode res = new ListNode(-1);
ListNode virtualHeadNode = res;
while (!listNodes.isEmpty()){
virtualHeadNode.next = listNodes.poll();
virtualHeadNode = virtualHeadNode.next;
if(virtualHeadNode.next != null) {
listNodes.add(virtualHeadNode.next);
}
}
virtualHeadNode.next = null;
return res.next;
}
}
- 总结:合并多个有序链表:使用优先权队列。队列里只存放头结点,取出一个头结点再加入下一个,避免有序结点相对顺序变化后最后形成环的问题,且时间复杂度
nlogk
,k为头结点数,即链表数;如果全部加入则nlogn
,且需要将最后加入的结点的next=null
,避免出现环。