合并 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个升序链表结束

相关推荐
Aileen_0v016 分钟前
【AI驱动的数据结构:包装类的艺术与科学】
linux·数据结构·人工智能·笔记·网络协议·tcp/ip·whisper
是小胡嘛17 分钟前
数据结构之旅:红黑树如何驱动 Set 和 Map
数据结构·算法
yuanManGan2 小时前
数据结构漫游记:静态链表的实现(CPP)
数据结构·链表
2401_858286116 小时前
115.【C语言】数据结构之排序(希尔排序)
c语言·开发语言·数据结构·算法·排序算法
猫猫的小茶馆6 小时前
【数据结构】数据结构整体大纲
linux·数据结构·算法·ubuntu·嵌入式软件
2401_858286117 小时前
109.【C语言】数据结构之求二叉树的高度
c语言·开发语言·数据结构·算法
huapiaoy7 小时前
数据结构---Map&Set
数据结构
南宫生7 小时前
力扣-数据结构-1【算法学习day.72】
java·数据结构·学习·算法·leetcode
yuanbenshidiaos7 小时前
数据结构---------二叉树前序遍历中序遍历后序遍历
数据结构
^南波万^7 小时前
数据结构--排序
数据结构