23. 合并 K 个升序链表 - 力扣(LeetCode)
题目描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
解题思路
合并两个有序链表,直接比较两个链表找出较小的节点插入新的链表即可。
合并k个有序链表,则需要找到k个链表中最小的节点,并将其插入新的链表中,然后将最小节点链表后移,继续比较k个链表中最小的节点,直到所有链表都为空。
可以使用优先队列将k个节点放入优先队列中,每次取出最小的节点插入新的链表中,并将其后移。
java
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) return null;
ListNode dummy = new ListNode(-1);
ListNode p = dummy;
PriorityQueue<ListNode> pq = new PriorityQueue<>(
lists.length, (a, b)->(a.val - b.val));
for(ListNode node : lists) {
if (node != null) {
pq.add(node);
}
}
while(!pq.isEmpty()) {
ListNode node = pq.poll();
p.next = node;
if(node.next != null) {
pq.add(node.next);
}
p = p.next;
}
return dummy.next;
}
}
kotlin
class Solution {
fun mergeKLists(lists: Array<ListNode?>): ListNode? {
val dummy = ListNode(-1)
var p = dummy
val pq = PriorityQueue<ListNode> { o1, o2 ->
o1.`val` - o2.`val`
}
lists?.forEach {
if (it != null) pq.offer(it)
}
while (pq.isNotEmpty()) {
val q = pq.poll()
p.next = q
p = p.next
if (q.next != null) pq.offer(q.next)
}
return dummy.next
}
}
go
func mergeKLists(lists []*ListNode) *ListNode {
if len(lists) == 0 {
return nil
}
dummy := &ListNode{Val: -1}
p := dummy
pq := make(PriorityQueue, 0)
heap.Init(&pq)
for _, node := range lists {
if node != nil {
heap.Push(&pq, node)
}
}
for pq.Len() > 0 {
node := heap.Pop(&pq).(*ListNode)
p.Next = node
if node.Next != nil {
heap.Push(&pq, node.Next)
}
p = p.Next
}
return dummy.Next
}
type PriorityQueue []*ListNode
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
if pq[i] != nil && pq[j] != nil {
return pq[i].Val < pq[j].Val
}
return false
}
func (pq PriorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
}
func (pq *PriorityQueue) Push(x interface{}) {
item := x.(*ListNode)
*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
*pq = old[0 : n-1]
return item
}