欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 合并K个升序链表

合并K个升序链表

2025/9/20 3:48:25 来源:https://blog.csdn.net/qq_58284486/article/details/148051046  浏览:    关键词:合并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;}

 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词