Java合并两个及以上有序链表的示例详解

目录
  • 题目一:合并两个有序链表
    • 题目一思路
    • 题目一完整代码
  • 题目二:合并多个有序链表
    • 题目二关键思路
    • 题目二完整代码

题目一:合并两个有序链表

题目链接

题目一思路

设置两个指针,一个指针(t1)指向l1链表头,另外一个指针(t2)指向l2链表头。

首先判断l1和l2的第一个元素,谁小,谁就是最后要返回的链表的头节点,如果l1和l2的第一个元素相等,随便取哪个都可以。

这样,我们就设置好了要返回链表的头节点,假设头节点是head,

依次移动t1和t2指针,谁小,谁就接入进来。依次操作,直到两个链表都遍历完毕为止。

此外,有个显而易见的结论:如果l1和l2有一个链表为空,则返回那个不为空的链表即可

题目一完整代码

public class LeetCode_0021_MergeTwoSortedLists {

    public static class ListNode {
        public int val;
        public ListNode next;
    }

    public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null || l2 == null) {
            // 如果任何一个链表为空,那么直接返回另外一个链表即可
            return l1 == null ? l2 : l1;
        }
        // 谁小谁作为头
        ListNode head = l1.val > l2.val ? l2 : l1;
        // t1 和 t2 表示l1和l2下一个要遍历的位置
        ListNode t1 = head == l1 ? l1.next : l1;
        ListNode t2 = head == l2 ? l2.next : l2;
        ListNode cur = head;
        while (t1 != null || t2 != null) {
            if (t1 == null) {
                // l1链表已经到头,剩下只需要把l2链表接入进来即可
                cur.next = t2;
                t2 = t2.next;
                cur = cur.next;
                continue;
            }
            if (t2 == null) {
                // l2链表已经到头,剩下只需要把l2链表接入进来即可
                cur.next = t1;
                t1 = t1.next;
                cur = cur.next;
                continue;
            }
            // l1和l2都没有到头,那么谁小谁接入进来即可。
            if (t1.val > t2.val) {
                cur.next = t2;
                t2 = t2.next;
            } else {
                cur.next = t1;
                t1 = t1.next;
            }
            cur = cur.next;
        }
        return head;
    }
}

题目二:合并多个有序链表

23. Merge k Sorted Lists

题目二关键思路

准备一个小根堆,并把每个链表的头节点加入到小根堆中,此时,小根堆堆顶弹出的节点一定是最后生成链表的头节点。

假设链表为:L1,L2...LN

第一步,先将L1,L2...LN的头节点L1H,L2H...LNH加入小根堆

第二步,从小根堆堆顶弹出一个元素,作为最后链表的头节点。

第三步,第二步中弹出节点所在的链表假设是i号链表,那么就找弹出节点的下一个位置(假设为X)再和小根堆堆顶元素比较:

如果X比堆顶元素大,则堆顶元素弹出,X进入小根堆

如果X比堆顶元素小,则直接不需要进入堆顶,作为结果链表

题目二完整代码

public class LeetCode_0023_MergeKSortedLists {

    public static class ListNode {
        int val;
        ListNode next;
    }

    public static ListNode mergeKLists(ListNode[] lists) {
        if (null == lists || lists.length == 0) {
            return null;
        }
        if (1 == lists.length) {
            return lists[0];
        }
        // 小根堆
        PriorityQueue<ListNode> queue = new PriorityQueue<>(Comparator.comparingInt(o -> o.val));
        for (ListNode list : lists) {
            if (null != list) {
                queue.add(list);
            }
        }
        ListNode res = queue.poll();
        ListNode head = res;
        while (!queue.isEmpty()) {
            if (res != null) {
                ListNode n = res.next;
                if (n == null) {
                    res.next = queue.poll();
                    res = res.next;
                } else if (n.val > queue.peek().val) {
                    res.next = queue.poll();
                    res = res.next;
                    queue.add(n);
                } else {
                    res = res.next;
                }
            }
        }
        return head;
    }
}

到此这篇关于Java合并两个及以上有序链表的示例详解的文章就介绍到这了,更多相关Java合并有序链表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java编程实现递增排序链表的合并

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解答: /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode Merge(ListNode list1,ListNode list2) { if(list1==null)

  • c++ 如何合并两个有序链表

    1.题目要求 这是一道求职面试时经常要求手写或者机试的经典题目. 已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序.结果链表要包含head1和head2的所有节点,即使节点值相同. 注意:不能开辟新空间来存储合并后的链表.如果第一次做该题,很容易会想到使用新链表来存储合并后的有序链表.虽然可以如此实现,但是不符合常规解法和面试官的要求. 2.非递归实现 算法过程:  输入:两个有序的单链表head1与head2:  输出:合并后的有序单链表mergeHead:  算法描

  • 带你了解如何用C++合并两个有序链表

    目录 将两个升序链表合并为一个新的 升序 链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 思路 代码 链表Listnode详细介绍 总结 将两个升序链表合并为一个新的 升序 链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例 1: 输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4] 示例 2: 输入:l1 = [], l2 = [] 输出:[] 示例 3: 输入:l1 = [], l2 = [0] 输出:[0] 思路 可以简

  • java编程题之合并两个排序的链表

    本文实例为大家分享了java合并两个排序的链表,供大家参考,具体内容如下 /** * * 剑指offer编程题(JAVA实现)--第16题:合并两个排序的链表 * * 输入两个单调递增的链表,输出两个链表合成后的链表, 当然我们需要合成后的链表满足单调不减规则. * */ public class Test16 { public static ListNode Merge(ListNode list1, ListNode list2) { if (list1 == null) { // 首先判断

  • Java合并两个及以上有序链表的示例详解

    目录 题目一:合并两个有序链表 题目一思路 题目一完整代码 题目二:合并多个有序链表 题目二关键思路 题目二完整代码 题目一:合并两个有序链表 题目链接 题目一思路 设置两个指针,一个指针(t1)指向l1链表头,另外一个指针(t2)指向l2链表头. 首先判断l1和l2的第一个元素,谁小,谁就是最后要返回的链表的头节点,如果l1和l2的第一个元素相等,随便取哪个都可以. 这样,我们就设置好了要返回链表的头节点,假设头节点是head, 依次移动t1和t2指针,谁小,谁就接入进来.依次操作,直到两个链

  • Java比较两个对象大小的三种方法详解

    目录 一. 为什么需要比较对象 二. 元素的比较 1. 基本类型的比较 2. 引用类型的比较 三. 对象比较的方法 1. equals方法比较 2. 基于Comparable接口的比较 3. 基于Comparator接口的比较 4. 三种比较方式对比 一. 为什么需要比较对象 上一节介绍了优先级队列,在优先级队列中插入的元素必须能比较大小,如果不能比较大小,如插入两个学生类型的元素,会报ClassCastException异常 示例: class Student{ String name; in

  • java开发Dubbo负载均衡与集群容错示例详解

    目录 负载均衡与集群容错 Invoker 服务目录 RegistryDirectory 获取Invoker列表 监听注册中心 刷新Invoker列表 StaticDirectory 服务路由 Cluster FailoverClusterInvoker FailfastClusterInvoker FailsafeClusterInvoker FailbackClusterInvoker ForkingClusterInvoker BroadcastClusterInvoker Abstract

  • java 与testng利用XML做数据源的数据驱动示例详解

    java 与testng利用XML做数据源的数据驱动示例详解 testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本.在这以XML为例: 备注:@DataProvider的返回值类型只能是Object[][]与Iterator<Object>[] TestData.xml: <?xml version="1.0" encoding="UTF-8"?> <

  • java数据结构图论霍夫曼树及其编码示例详解

    目录 霍夫曼树 一.基本介绍 二.霍夫曼树几个重要概念和举例说明  构成霍夫曼树的步骤 霍夫曼编码 一.基本介绍 二.原理剖析 注意: 霍夫曼编码压缩文件注意事项 霍夫曼树 一.基本介绍 二.霍夫曼树几个重要概念和举例说明  构成霍夫曼树的步骤 举例:以arr = {1  3  6  7  8   13   29}  public class HuffmanTree { public static void main(String[] args) { int[] arr = { 13, 7, 8

  • java线程池ThreadPoolExecutor的八种拒绝策略示例详解

    目录 池化设计思想 线程池触发拒绝策略的时机 JDK内置4种线程池拒绝策略 拒绝策略接口定义 AbortPolicy(中止策略) DiscardPolicy(丢弃策略) DiscardOldestPolicy(弃老策略) 第三方实现的拒绝策略 Dubbo 中的线程拒绝策略 Netty 中的线程池拒绝策略 ActiveMQ 中的线程池拒绝策略 PinPoint 中的线程池拒绝策略 谈到 Java 的线程池最熟悉的莫过于 ExecutorService 接口了,jdk1.5 新增的 java.uti

  • java比较两个list是否相同equals的代码详解

    比较两个list是否相同,一般我用数组自带的函数equals,如: public int updateTemplateByVO(ContentTemplateVO contentTemplateVO) throws Exception { int flag = 0; if (null == contentTemplateVO) { return flag; } //比较新编辑的模板参数是否与原有的参数相同 //新的参数数组 List<String> stringList = getParamL

  • Java中的魔法类:sun.misc.Unsafe示例详解

    前言 Unsafe类在jdk 源码的多个类中用到,这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率.但是,它是一把双刃剑:正如它的名字所预示的那样,它是Unsafe的,它所分配的内存需要手动free(不被GC回收).Unsafe类,提供了JNI某些功能的简单替代:确保高效性的同时,使事情变得更简单. 这个类是属于sun.* API中的类,并且它不是J2SE中真正的一部份,因此你可能找不到任何的官方文档,更可悲的是,它也没有比较好的代码文档. 这篇文章主要是以下文章的整理.翻译.

  • Java并发编程包中atomic的实现原理示例详解

    线程安全: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协调,这个类都能表现出正确的行为,那么就称这个类时线程安全的. 线程安全主要体现在以下三个方面: 原子性:提供了互斥访问,同一时刻只能有一个线程对它进行操作 可见性:一个线程对主内存的修改可以及时的被其他线程观察到 有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序的存在,该观察结果一般杂乱无序 引子 在多线程的场景中,我们需要保证数据安全,就会考虑同步的

  • JS实现的合并两个有序链表算法示例

    本文实例讲述了JS实现的合并两个有序链表算法.分享给大家供大家参考,具体如下: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 可以直接运行的方案: <script> function Node(element) { this.element = element;//当前节点的元素 this.next = n

随机推荐