LeetCode Meditations:合并 K 排序列表

这篇具有很好参考价值的文章主要介绍了LeetCode Meditations:合并 K 排序列表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

LeetCode Meditations:合并 K 排序列表,LeetCode,算法,leetcode,算法,javascript,数据结构

描述 合并K分类列表 状态:

您有一系列 k 链接-列表 lists ,每个链接-列表按升序排序。

合并所有链接-列表为一个排序的链接-列出并返回。

例如:

Input: lists = [[1, 4, 5], [1, 3, 4], [2, 6]]
Output: [1, 1, 2, 3, 4, 4, 5, 6]
Explanation: The linked-lists are:
[
  1->4->5,
  1->3->4,
  2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6

起初这个问题有点让我感到困惑,但是 NEETCODE 很有意义。

解决方案的方法是 合并排序算法 ,这是您从任何介绍性计算机科学课程中可能记得的最熟悉的算法之一。

现在,当我们将数组作为输入作为输入时,我们通常会合并排序,我们将数组递归将数组分为左和右半,并继续合并它们,直到整个数组对整个数组进行排序。这是我们熟悉的朋友在JavaScript中的样子:

function mergeSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }

  let left = arr.slice(0, Math.floor(arr.length / 2));
  let right = arr.slice(Math.floor(arr.length / 2), arr.length);

  mergeSort(left);
  mergeSort(right);

  merge(left, right, arr);

  return arr;
}


function merge(left, right, arr) {
  let index = 0;

  while (left.length && right.length) {
    if (left[0] < right[0]) {
      arr[index++] = left.shift();
    } else {
      arr[index++] = right.shift();
    }
  }

  while (left.length) {
    arr[index++] = left.shift();
  }

  while (right.length) {
    arr[index++] = right.shift();
  }
}

但是,我们要使用的是 * merge 功能。

由于我们还使用链接列表,因此看起来会有所不同。使用TypeScript,看起来像这样:

function merge(list1: ListNode | null, list2: ListNode | null) {
  let result = new ListNode(0);
  let currentNode = result;

  while (list1 !== null && list2 !== null) {
    if (list1.val < list2.val) {
      currentNode.next = list1;
      list1 = list1.next;
    } else {
      currentNode.next = list2;
      list2 = list2.next;
    }

    currentNode = currentNode.next;
  }

  if (list1 !== null) {
    currentNode.next = list1;
  }

  if (list2 !== null) {
    currentNode.next = list2;
  }

  return result.next;
}

自从我们给予 k 排序列表,我们将合并列表对,并继续合并 lists 大于1:

function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
  if (lists === null || lists.length === 0) {
    return null;
  }

  while (lists.length > 1) {
    let mergedLists = [];
    for (let i = 0; i < lists.length; i += 2) {
      let list1 = lists[i];
      let list2 = i + 1 < lists.length ? lists[i + 1] : null;
      mergedLists.push(merge(list1, list2));
    }

    lists = mergedLists;
  } 

  return lists[0];
};
笔记
如果 list2null (在长度的情况下 lists 甚至不是),合并 list1list2 将是 list1

总体而言,解决方案看起来像这样:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *   val: number
 *   next: ListNode | null
 *   constructor(val?: number, next?: ListNode | null) {
 *     this.val = (val === undefined ? 0 : val)
 *     this.next = (next === undefined ? null : next)
 *   }
 * }
 */

function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
  if (lists === null || lists.length === 0) {
    return null;
  }

  while (lists.length > 1) {
    let mergedLists = [];
    for (let i = 0; i < lists.length; i += 2) {
      let list1 = lists[i];
      let list2 = i + 1 < lists.length ? lists[i + 1] : null;
      mergedLists.push(merge(list1, list2));
    }

    lists = mergedLists;
  } 

  return lists[0];
};

function merge(list1: ListNode | null, list2: ListNode | null) {
  let result = new ListNode(0);
  let currentNode = result;

  while (list1 !== null && list2 !== null) {
    if (list1.val < list2.val) {
      currentNode.next = list1;
      list1 = list1.next;
    } else {
      currentNode.next = list2;
      list2 = list2.next;
    }

    currentNode = currentNode.next;
  }

  if (list1 !== null) {
    currentNode.next = list1;
  }

  if (list2 !== null) {
    currentNode.next = list2;
  }

  return result.next;
}
时间和空间复杂性

时间复杂性是o(n log k)o(n\ log\ k) - 也看 NEETCODE的解释 - ,如果您记得合并排序功能的时间复杂性是o(n log n)o(n\ 日志\ n) :我们通过合并操作中的每个项目,但是由于每次输入都会减半,我们会记录NLOG\ n次。在这里类似,nn是指节点的数量,而kk是列表的数量。
空间复杂性是O(k)o(k) 当我们保留临时的时,kk是列表的数量 mergedLists 多变的。文章来源地址https://www.toymoban.com/news/detail-851178.html


到了这里,关于LeetCode Meditations:合并 K 排序列表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Leetcode -21.合并两个有序链表 -83.删除排序链表中的重复元素】

    题目:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 = [1, 2, 4], l2 = [1, 3, 4] 输出:[1, 1, 2, 3, 4, 4] 示例 2: 输入:l1 = [], l2 = [] 输出:[] 示例 3: 输入:l1 = [], l2 = [0] 输出:[0] 我们的思路是,先定义

    2023年04月24日
    浏览(35)
  • 【算法之贪心算法IV】leetcode56. 合并区间

    力扣题目链接 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中 points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend 之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭

    2024年02月11日
    浏览(41)
  • LeetCode面试算法-力扣 88. 合并两个有序数组

    88. 合并两个有序数组 题目描述     给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意: 最终,合并后数组不应由函数返回,而是存储

    2024年02月10日
    浏览(34)
  • Leetcode算法递归类—合并两个有序链表

    目录 21. 合并两个有序链表 题解: 代码: 将两个升序链表合并为一个新的  升序  链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。  示例 1: 示例 2: 示例 3: 提示: 两个链表的节点数目范围是  [0, 50] -100 = Node.val = 100 l1  和  l2  均按  非递减顺序  

    2024年02月13日
    浏览(29)
  • 算法leetcode|88. 合并两个有序数组(rust重拳出击)

    给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2 ,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意 :最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况

    2024年02月05日
    浏览(36)
  • 算法沉淀——BFS 解决拓扑排序(leetcode真题剖析)

    Breadth-First Search (BFS) 在拓扑排序中的应用主要是用来解决有向无环图(DAG)的拓扑排序问题。拓扑排序是对有向图中所有节点的一种线性排序,使得对于每一条有向边 (u, v),节点 u 在排序中都出现在节点 v 的前面。如果图中存在环路,则无法进行拓扑排序。 BFS 解决拓扑排序

    2024年02月21日
    浏览(30)
  • 【LeetCode 算法】Merge k Sorted Lists 合并 K 个升序链表

    给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 k = = l i s t s . l e n g t h 0 = k = 1 0 4 0 = l i s t s [ i ] . l e n g t h = 500 − 1 0 4 = l i s t s [ i ] [ j ] = 1 0 4 l i s t s [ i ] 按升序排列 l i s t s [ i ] . l e n g t h 的总和不超过 1 0

    2024年02月13日
    浏览(25)
  • 【算法】排序+双指针——leetcode三数之和、四数之和

    三数之和 (1)排序+双指针   算法思路: 和之前的两数之和类似,我们对暴力枚举进行了一些优化,利用了 排序+双指针 的思路:   我们先排序,然后固定⼀个数 a ,接着我们就可以在这个数后面的区间内,使用之前两数之和使用的算法,快速找到两个数之和和固定的

    2024年02月13日
    浏览(40)
  • 算法leetcode|81. 搜索旋转排序数组 II(rust重拳出击)

    已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。 在传递给函数之前, nums 在预先未知的某个下标 k ( 0 = k nums.length )上进行了 旋转 ,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (下标 从 0 开始 计数)。例如, [0,1,2,4,4,4,5,6,

    2024年02月07日
    浏览(35)
  • 【leetcode刷题之路】剑指Offer(4)——分治+排序算法+动态规划

    8 分治算法 8.1 【递归】剑指 Offer 07 - 重建二叉树 https://leetcode.cn/problems/zhong-jian-er-cha-shu-lcof/   前序遍历是根左右,中序遍历是左根右,这也就意味着前序遍历的第一个节点是整棵树的根节点,顺着这个节点找到它在中序遍历中的位置,即为in_root,那么in_root左边的都在左子

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包