合并 K 个升序链表

合并2个升序链表

首先想要合并k个升序链表要先明白如何合并2个升序链表

链表节点的结构为:

java 复制代码
public class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

循环判断两个链表的值大小关系,将小的那个赋值到新创建链表节点的下一个,循环结束后其中一个链表可能还未全部遍历,将其赋值在当前节点的next即可。

java 复制代码
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        //创建头节点和临时节点,头节点用于返回结果,临时节点用于不断给下一个赋值
        ListNode newList = new ListNode();
        ListNode tmp = newList;

        while(list1 != null && list2 != null) {
            if(list1.val <= list2.val){    //如果第一个列表的当前值小于等于第二个列表的当前值
                tmp.next = list1;          //将第一个列表的的当前节点赋值到临时节点的下一个
                list1 = list1.next;        //移动到下一个
            }else{                         //第二个列表当前值小于第一个列表当前值
                tmp.next = list2;          //将第二个列表的的当前节点赋值到临时节点的下一个
                list2 = list2.next;
            }
            tmp = tmp.next;                //临时节点移动到下一个
        }

        //使用三木运算符判断某个列表是否还未循环结束,若有赋值到临时节点的下一个即可
        tmp.next = list1 != null ? list1 : list2;
        //返回头的下一个即可
        return newList.next;
    }
}

分治法

分治思想:

将多个数据,先进行对半拆分,分到都剩最后一个链表时返回当前链表,在将两个链表进行合并排序。

到最后全部拆分的链表合并为一个时,结束算法。

合并 K 个升序链表

使用分治法,先对半拆分,将k个链表分成左半部分和右半部分,直到结束条件(当前只剩一条链表)时返回当前链表。

设计一个方法sort,分别需要参数总链表lists,左边索引值start和右边索引值end。当左边索引等于右边索引时,返回lists[start]

此时左半部分和右半部分会返回一条升序的链表,为左半部分升序链表(后面都称为左链)和右半部分升序链表(后面都称为右链),使用合并两个升序链表合并思想将左链和右链合并为一条升序链表,返回当前升序链表。

进行多次的拆分和合并递归后最终由k个升序链表得到一条升序链表。

java 复制代码
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;//当前列表为空或长度为0返回null
        return sort(lists, 0, lists.length - 1);
    }

    public ListNode sort(ListNode[] lists, int start, int end) {
        if (start == end)                           //结束条件,即只剩一条链表时返回
            return lists[start];

        int i = (end + start) / 2;                  //根据左右两个索引获得中间索引值
        ListNode left = sort(lists, start, i);      //拆分为left和right部分
        ListNode right = sort(lists, i + 1, end);   //此时两个返回值都是一条升序链表

        ListNode head = new ListNode(), tem = head; //设置头节点
                                                    //后续代码和合并2条有序链表代码相同
        while(left != null && right != null) {
            if (left.val <= right.val){
                tem.next = left;
                left = left.next;
            }
            else{
                tem.next = right;
                right = right.next;
            }
            tem = tem.next;
        }

        if(left != null)
            tem.next = left;
        if(right != null)
            tem.next = right;

        return head.next;
    }
}

至此合并k个升序链表结束

相关推荐
Wyc7240921 分钟前
数据结构1
数据结构
lcj251132 分钟前
【数据结构精讲】堆与二叉树从底层原理到代码落地:堆的构建 / 调整 / 排序 + 二叉树遍历 / 操作(附完整 C++ 源码 + LeetCode 题解)
数据结构·c++·leetcode
努力努力再努力wz33 分钟前
【MySQL 进阶系列】C/C++ 如何通过客户端库访问 MySQL?从连接原理到 API 调用流程详解(附完整demo代码)
服务器·c语言·数据结构·数据库·c++·b树·mysql
xuhaoyu_cpp_java35 分钟前
单调栈(算法)
java·数据结构·经验分享·笔记·学习·算法
诙_1 小时前
C++数据结构--排序算法
数据结构·算法·排序算法
许彰午2 小时前
02-手写链表、栈、队列——不依赖任何集合框架
数据结构·链表·面试
MegaDataFlowers2 小时前
141.环形链表
数据结构·链表
JAVA面经实录91711 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
浅念-11 小时前
「一文吃透 BFS:从层序遍历到锯齿形、最大宽度、每层最大值」
数据结构·算法
苍煜14 小时前
二叉树、红黑树、B树、B+树通俗教学:各自适配场景+MySQL索引终极选型原因
数据结构·b树·mysql