[路飞]_合并K个升序链表

135 阅读1分钟

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

题解

直接合并

比较简单,合并写一个合并两个链表的方法,因为链表已经按照升序排列好;所以只需要枚举数组,将链表逐一合并即可。

代码

var mergeKLists = function (lists) {
  const len = lists.length
  if (len === 0) return null
  if (len === 1) return lists[0]
  let start = lists[0]
  for (let i = 1; i < len; i++) {
    const curr = lists[i]
    start = mergeTwoListNode(start, curr)
  }
  return start

  function mergeTwoListNode(l1, l2) {
    if (l1 === null) return l2
    if (l2 == null) return l1
    if (l1.val < l2.val) {
      l1.next = mergeTwoListNode(l1.next, l2)
      return l1
    } else {
      l2.next = mergeTwoListNode(l1, l2.next)
      return l2
    }
  }
}

分治

上一方法中逐一合并,速度较慢,可以使用分治思想将数组内链表两两;

代码

var mergeKLists = function (lists) {
  const len = lists.length
  if (len === 0) return null

  while (lists.length > 1) {
    const p1 = lists.pop() || null
    const p2 = lists.pop() || null
    const node = mergeList(p1, p2)
    lists.unshift(node)
  }

  return lists[0]

  // 合并两个链表
  function mergeList(node1, node2) {
    if (node1 === null) return node2
    if (node2 === null) return node1
    if (node1.val < node2.val) {
      node1.next = mergeList(node1.next, node2)
      return node1
    } else {
      node2.next = mergeList(node2.next, node1)
      return node2
    }
  }
}