24. 合并K个升序链表【LC23】

117 阅读2分钟

题目:

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

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

示例 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 = [[]]
输出:[]

核心思路:

按照链表lists的长度len,指定len个指针,遍历,时间复杂度Onk。

  • 整体循环终止条件: 当每个链表的头指针遍历一遍后,最小值状态变量仍为空,此时所有链表均已遍历完成。
  • 每轮循环中,两个状态变量进行运算记录,一个记录当前最小值节点,一个记录最小值节点所属链表。
  • 一轮循环中,分场景处理:
>(1)当前指针指向的当前节点为空,continue;
>(2)当前指针指向的节点不为空,最小值状态min为空,直接赋值给min,记录所属链表;
>(3)当前指针指向的节点不为空,最小值状态min也不为空,比较值大小,跟新最小值状态min以及所属链表;
>(4)一轮循环完成后,所属链表后移一位;

解:

var mergeKLists = function (lists) {
  let len = lists.length;
  const newHeader = {};
  let temp = newHeader;
  while (true) {
    let min = null;
    let idx = 0;
    for (let i = 0; i < len; i++) {
      if (!lists[i]) { // 当前指针指向的当前节点为空
        continue
      } else { // 当前指针指向的当前节点不为空
        if (!min) { // 当前指针指向的当前节点不为空,但是min为空
          min = lists[i];
          idx = i;
        } else { // 当前指针指向的当前节点不为空,min不为空,更新最小值
          if (lists[i].val < min.val) {
            min = lists[i]; // 记录更小的节点
            idx = i; // 记录更小节点所属链表,最后要从链表中移除当前节点
          }
        }
      }
    }
    temp.next = min;
    if (!min) { //终止条件:每个链表指针均为空
      break
    }
    lists[idx] = lists[idx].next; // 最小节点所属链表后移
    temp = temp.next;
  }
  return newHeader.next;
};

———— 前端、Javascript实现、算法、刷题、leetcode