当前位置: 首页 > news >正文

合并K个升序链表

目录

合并 K 个升序链表 

解题思路 

ListNode 数组方式给出 k 个链表

ArrayList 方式给出 k 个链表 

ArrayList常见操作


合并 K 个升序链表 

题目描述

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

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

示例 1

输入:lists = [[1,4,5],[1,3,4],[2,6]]

输出:[1,1,2,3,4,4,5,6]

        有两种方式给出 k 个链表,一种是以 ListNode 数组的方式给出链表,另一种方式是以 List Node 顺序表的方式给出,本文以 合并 k 个升序链表为例,顺便复习 ArrayList

解题思路 

        对于 k 个有序链表的合并,其实就相当于对这 k 个链表首先两两进行合并,得到合并后的     k / 2个链表,之后继续对这 k / 2 的链表进行合并,得到 k / 4 个链表,对其以此类推一直进行合并,直到为数量为 1 为止,这个链表就是 k 个链表合并后的结果。 

        其关键在于:1、如何对两个链表进行合并,对于该问题可以在leetcode中练习:合并两个有序链表,在该题目中,我们将两个链表进行合并封装成一个函数;2、如何对 1 中的函数传参,这是每次传入哪两个链表,这里有两种方式:①一种是将相邻的两个链表传入,②另一种是每次传入最左边和最右边这两个链表。

ListNode 数组方式给出 k 个链表

        以下代码给出了两种传入两个链表的方式,第一种将相邻的两个链表传入借助 for 循环即可实现,第二种每次传入最左边和最右边这两个链表,借助双指针即可实现,具体见下列代码. 

    /*** 每次传入最左边和最右边的链表*/public ListNode mergeKLists(ListNode[] lists) {if (lists == null || lists.length == 0) {return null;}int len = lists.length;while (len > 1) {int index = 0;int left = 0;int right = len - 1;while (left < right) {lists[index++] = merge(lists[left], lists[right]);left++;right--;}if (left == right) {lists[index++] = lists[left];}len = index;}return lists[0];}/*** 每次将相邻的两个链表传入*/public ListNode mergeKLists(ListNode[] lists) {if (lists == null || lists.length == 0) {return null;}int len = lists.length;while (len > 1) {int index = 0;for (int i = 0; i < len; i += 2) {if (i == len - 1) {lists[index++] = lists[i];} else {lists[index++] = merge(lists[i], lists[i + 1]); }}len = index;}return lists[0];}private ListNode merge(ListNode head1, ListNode head2) {if (head1 == null || head2 == null) {return head1 == null ? head2 : head1;}ListNode newHead = new ListNode(-1); // 虚拟节点ListNode cur = newHead;while (head1 != null && head2 != null) {if (head1.val > head2.val) {cur.next = head2;head2 = head2.next;cur = cur.next;} else {cur.next = head1;head1 = head1.next;cur = cur.next;}}cur.next = head1 == null ? head2 : head1;return newHead.next;}

ArrayList 方式给出 k 个链表 

ArrayList常见操作

1. boolean add(E e)    // 尾插 e 

2. void add(int index, E e)  // 在 index 位置插入 e

3. E remove(int index)  // 删除 index 位置的元素

4. E get(int index)  // 获取 index 下标的元素

5. E set(int index, E e)  // 将 index 下标的值改为 e

6. void clear()  // 清空所有元素

7. boolean contains(Object o)  // 判断 o 是否在线性表中

8. int indexOf(Object o)  // 返回第一个 o 的下标

9. int lastIndexOf(Object o)  // 返回最后一个 o 的下标

        对于该题, 可以以 ArrayList 的方式传入要合并的链表, 实现思路与以数组方式传入链表一样,但需要熟悉 ArrayList 相关的操作,具体代码实现方式如下:

    /*** 每次传入最左边和最右边的链表*/public static ListNode mergeKLists(ArrayList<ListNode> lists) {if (lists == null || lists.size() == 0) {return null;}int len = lists.size();while (len > 1) {int index = 0;int left = 0;int right = len - 1;while (left < right) {lists.set(index++, merge(lists.get(left), lists.get(right)));left++;right--;}if (left == right) {lists.set(index++, lists.get(left));}len = index;}return lists.get(0);}/*** 每次将相邻的两个链表传入*/public static ListNode mergeKLists2(ArrayList<ListNode> lists) {if (lists == null || lists.size() == 0) {return null;}int len = lists.size();while (len > 1) {int index = 0;for (int i = 0; i < len; i += 2) {if (i == len - 1) {lists.set(index++, lists.get(i));} else {lists.set(index++, merge(lists.get(i), lists.get(i + 1)));}}len = index;}return lists.get(0);}private static ListNode merge(ListNode head1, ListNode head2) {if (head1 == null || head2 == null) {return head1 == null ? head2 : head1;}ListNode newHead = new ListNode(-1); // 虚拟节点ListNode cur = newHead;while (head1 != null && head2 != null) {if (head1.val > head2.val) {cur.next = head2;head2 = head2.next;cur = cur.next;} else {cur.next = head1;head1 = head1.next;cur = cur.next;}}cur.next = head1 == null ? head2 : head1;return newHead.next;}

 

 

相关文章:

  • jenkins pipeline实现CI/CD
  • Java中的伪共享(False Sharing):隐藏的性能杀手与高并发优化实战
  • 安卓应用层抓包通杀脚本 r0capture 详解
  • 贝叶斯公式:用新证据更新旧判断: P(B∣A)⋅P(A)
  • Java正则表达式:从基础到高级应用全解析
  • 第4章 部署与固件发布:OTA、版本管理与制品仓库
  • Python爬虫实战:通过PyExecJS库实现逆向解密
  • 深度估计中为什么需要已知相机基线(known camera baseline)?
  • C++23 放宽范围适配器以允许仅移动类型(P2494R2)
  • vmware虚拟机运行多个产生卡顿问题
  • Spring源码主线全链路拆解:从启动到关闭的完整生命周期
  • 微服务项目->在线oj系统(Java版 - 1)
  • Vue-计算属性
  • 【QGIS二次开发】地图编辑-09
  • 1-机器学习的基本概念
  • 网络流算法
  • 进程与线程:10 信号量临界区保护
  • 【通用智能体】Serper API 详解:搜索引擎数据获取的核心工具
  • Redis 学习笔记 4:优惠券秒杀
  • GEE谷歌地球引擎批量下载逐日ERA5气象数据的方法
  • 上海迪士尼蜘蛛侠主题园区正式动工,毗邻“疯狂动物城”
  • 以开放促发展,以发展促开放,浙江加快建设高能级开放强省
  • 种植耐旱作物、启动备用水源,甘肃各地多举措应对旱情
  • 家国万里·时光故事会|构筑中国船舰钢筋铁骨,她在焊花里展现工匠风范
  • 纪念|脖子上挂着红领巾的陈逸飞
  • 上海:到2027年,实现近海航线及重点海域5G网络高质量覆盖