23. 合并K个升序链表

Posted 沿着路走到底

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了23. 合并K个升序链表相关的知识,希望对你有一定的参考价值。

力扣

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6


示例 2:

输入:lists = []
输出:[]


示例 3:

输入:lists = [[]]
输出:[]

解题思路

新链表的下一个节点一定是 K个链表 头中的最小节点

考虑使用最小堆。

解题步骤

构建一个最小堆,并依次把链表头插入堆中。

弹出堆顶接到输出链表,并将堆顶所在链表的新链表头插入堆中。

等堆元素全部弹出,合并工作就完成了。

class MinHeap 
  constructor() 
    this.heap = []
  

  swap(parentIndex, childIndex) 
    const temp = this.heap[parentIndex]
    this.heap[parentIndex] = this.heap[childIndex]
    this.heap[childIndex] = temp
  

  getParentIndex(index) 
    //return Math.floor((index - 1) / 2)
    return (index - 1) >> 1
  

  getLeftIndex(index) 
    return index * 2 + 1
  

  getRightIndex(index) 
    return index * 2 + 2
  

  shiftUp(index) 
    if (index === 0) return

    const parentIndex = this.getParentIndex(index)
    if(this.heap[parentIndex] && this.heap[parentIndex].val > this.heap[index].val) 
      this.swap(parentIndex, index)
      this.shiftUp(parentIndex)
    
  

  shiftDown(index) 
    const leftIndex = this.getLeftIndex(index)
    const rightIndex = this.getRightIndex(index)

    if(this.heap[leftIndex] && this.heap[index].val > this.heap[leftIndex].val) 
      this.swap(index, leftIndex)
      this.shiftDown(leftIndex)
    

    if(this.heap[rightIndex] && this.heap[index].val > this.heap[rightIndex].val) 
      this.swap(index, rightIndex)
      this.shiftDown(rightIndex)
    
  

  insert (value) 
    this.heap.push(value)
    this.shiftUp(this.heap.length - 1)
  

  pop () 
    if(this.size() === 1) return this.heap.shift()
    const top = this.heap[0]
    this.heap[0] = this.heap.pop()
    this.shiftDown(0)
    return top
  

  peek() 
    return this.heap[0]
  

  size() 
    return this.heap.length
  
  


/**
 * Definition for singly-linked list.
 * function ListNode(val, next) 
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * 
 */
/**
 * @param ListNode[] lists
 * @return ListNode
 * 
解题思路
新链表的下一个节点一定是 K个链表 头中的最小节点
考虑使用最小堆。

解题步骤
构建一个最小堆,并依次把链表头插入堆中。
弹出堆顶接到输出链表,并将堆顶所在链表的新链表头插入堆中。
等堆元素全部弹出,合并工作就完成了。
*/
var mergeKLists = function(lists) 
  const res = new ListNode(0)
  let p = res
  const h = new MinHeap()

  lists.forEach(l => 
    if (l) 
      h.insert(l)
    
  )

  while(h.size()) 
    const n = h.pop()
    p.next = n
    p = p.next
    if(n.next) h.insert(n.next)
  

  return res.next
;

1

以上是关于23. 合并K个升序链表的主要内容,如果未能解决你的问题,请参考以下文章

算法leetcode|23. 合并K个升序链表(rust重拳出击)

23. 合并K个升序链表

23. 合并K个升序链表

23. 合并K个升序链表

23. 合并K个升序链表

23. 合并K个升序链表 Java