合并k个排序列表
时间:2021-09-17
本文章向大家介绍合并k个排序列表,主要包括合并k个排序列表使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
给你一个链表数组,每个链表都已经按升序排列。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下: [ 1->4->5, 1->3->4, 2->6 ] 将它们合并到一个有序链表中得到。 1->1->2->3->4->4->5->6
示例 2:
输入:lists = [] 输出:[]
示例 3:
输入:lists = [[]] 输出:[]
提示:
k == lists.length 0 <= k <= 10^4 0 <= lists[i].length <= 500 -10^4 <= lists
方法一:利用数组比较
/** * Definition for singly-linked list. * 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; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) return null; // 将所有节点添加到数组中 List<ListNode> nodes = new ArrayList<>(); for (ListNode list : lists) { while (list != null) { nodes.add(list); list = list.next; } } // 对数组进行排序 nodes.sort((ListNode node1, ListNode node2) -> { return node1.val - node2.val; }); // 将排好序的节点串起来 ListNode head = new ListNode(0); ListNode cur = head; for (ListNode node: nodes) { cur = cur.next = node; } return head.next; } }
方法二:逐一比较
/** * Definition for singly-linked list. * 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; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) return null; ListNode head = new ListNode(0); ListNode cur = head; while (true) { // 最小链表节点所在的索引 int minIndex = -1; for (int i = 0; i < lists.length; i++) { if (lists[i] == null) continue; if (minIndex == -1 || lists[i].val < lists[minIndex].val) { minIndex = i; } } // 所有链表节点已经串起来了 if (minIndex == -1) break; cur = cur.next = lists[minIndex]; lists[minIndex] = lists[minIndex].next; } return head.next; } }
方法三:逐一两两合并
/** * Definition for singly-linked list. * 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; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) return null; for (int i = 1; i < lists.length; i++) { lists[0] = mergeTwoLists(lists[0], lists[i]); } return lists[0]; } // 虚拟头结点 private ListNode head = new ListNode(0); public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; head.next = null; ListNode cur = head; while (l1 != null && l2 != null) { if (l1.val <= l2.val) { cur = cur.next = l1; l1 = l1.next; } else { cur = cur.next = l2; l2 = l2.next; } } if (l1 == null) { cur.next = l2; } else if (l2 == null) { cur.next = l1; } return head.next; } }
方法四:小顶堆
/** * Definition for singly-linked list. * 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; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) return null; ListNode head = new ListNode(0); ListNode cur = head; // 将所有的链表的头节点添加到小顶堆(优先级队列)中 PriorityQueue<ListNode> queue = new PriorityQueue<>((ListNode node1, ListNode node2) -> { return node1.val - node2.val; }); for (ListNode list: lists) { if (list == null) continue; queue.offer(list); } // 不断删除堆顶元素,并且把堆顶元素的next添加到堆中 while (!queue.isEmpty()) { // 删除堆顶元素 ListNode node = queue.poll(); cur = cur.next = node; if (node.next != null) { queue.offer(node.next); } } return head.next; } }
方法五:分治策略
/** * Definition for singly-linked list. * 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; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) return null; int step = 1; while (step < lists.length) { int nextStep = step << 1; for (int i = 0; i+step < lists.length; i += nextStep) { lists[i] = mergeTwoLists(lists[i], lists[i+step]); } step = nextStep; } return lists[0]; } // 虚拟头结点 private ListNode head = new ListNode(0); public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; head.next = null; ListNode cur = head; while (l1 != null && l2 != null) { if (l1.val <= l2.val) { cur = cur.next = l1; l1 = l1.next; } else { cur = cur.next = l2; l2 = l2.next; } } if (l1 == null) { cur.next = l2; } else if (l2 == null) { cur.next = l1; } return head.next; } }
原文地址:https://www.cnblogs.com/constyang/p/15305161.html
- ASP.NET Core的配置(3): 将配置绑定为对象[上篇]
- ASP.NET的路由系统:URL与物理文件的分离
- 使用Excel分析CloudStack使用记录
- 卷积神经网络初探索
- TensorFlow 深度学习笔记 逻辑回归 实践篇
- 黑客是如何实施暴力破解的?
- Python的初学者你现在可以自己“看”到代码的运行了!
- ASP.NET Core的配置(3): 将配置绑定为对象[下篇]
- TensorFlow 深度学习笔记 从线性分类器到深度神经网络
- 微信版12306来了!用12306微信小程序买票靠谱吗
- 无需写try/catch,也能正常处理异常
- “人工智能毁灭人类”是一种末世恐惧传染病
- 有状态(Stateful)应用的容器化
- 实现一些字符串操作标准库函数、解决一些字符串问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Oracle基本概念(Undo空间)
- [AWR报告]Buffer Hit %
- [AWR报告]Library Hit %
- [Oracle 9i安装]Redhat 4.8的配置
- [Oracle 9i安装]Oracle软件的安装
- [AWR报告]Latch Hit %
- [Python运维]Python3.6的安装
- [Python运维]cx_Oracle模块的安装
- C#中抽象类与抽象方法的作用与实例
- C++ 基础扫盲(1)
- [Python运维]使用cx_Oracle连接Oracle(高级篇)
- [Python运维]使用Python发送邮件
- [Python运维]自动化监控Oracle表空间并发送报警
- [Python运维]自动化监控多个Oracle表空间
- c# 动态生成控件