合并k个排序链表
Posted 排序和map
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并k个排序链表相关的知识,希望对你有一定的参考价值。
方法一:堆
[抄题]:
合并k个排序链表,并且返回合并后的排序链表。尝试分析和描述其复杂度。
[思维问题]:
[一句话思路]:
堆的基本操作
- 堆是私有数据类型要加分号, 写在merge函数外面因为要调用。要加private 里面有public int函数(函数的参数在圆括号里) 返回的是left right节点的数值
- heap数据类型里有俩参数:lists.size()用来逐个放入, ListNodeComparator list非空时才需要放入 heap判空用!heap.isEmpty()
- list为空或者长度为0,可能导致无法merge
- dummy由于没有head, tail,都需要自己写 tail用来添加,head用来揪,放在循环体里面表示每次揪下来的都不一样
- heap揪下来后,判断余下是否非空,非空则继续添加
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
[总结]:
用比较函数+堆的做法
两个好基友的移动添加=连接+指针移动
[复杂度]:Time complexity: O(nlgk) Space complexity: O(1) 最多是k,常数级别
[英文数据结构,为什么不用别的数据结构]:
ArrayList vs LinkedList二者的区别:
1 ArrayList
是一个类,所以它持有了所有类的属性.例如,你可以创建对象,可以调用方法,但array
并不提供任何方法. 它仅仅暴露了一个常量的长度来表示当前数组的长度.
2 ArrayList
是动态的,它可以在需要的时候扩大自己的内存,这是一个 array
不可能做到的.ArrayList
也允许你删除元素, 这在array
上也是不可能的.
3 array
可以使多维度的.例如,你可以设置一个二维数组或者三维数组.可以使你创在一个特殊的数据结构来代表矩阵或者2D形式(terrains
),另一方面,ArrayList
并不支持允许你指定维度
[其他解法]:
2种nlgk的
[Follow Up]:
[题目变变变]:
合并k个排序数组 · Merge k Sorted Arrays:思想一样,写法上更麻烦一些
/** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { * this.val = val; * this.next = null; * } * } */ public class Solution { /** * @param lists: a list of ListNode * @return: The head of one sorted list. */ //comparator private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>() { public int compare(ListNode left, ListNode right) { return left.val - right.val; } }; public ListNode mergeKLists(ListNode[] lists) { //new heap if (lists.length == 0 || lists == null) { return null; } Queue<ListNode> heap = new PriorityQueue<ListNode>(lists.length,ListNodeComparator); for (int i = 0; i < lists.length; i++) { if (lists[i] != null) { heap.add(lists[i]); } } //add to the lists ListNode dummy = new ListNode(0); ListNode tail = dummy; while(!heap.isEmpty()) { ListNode head = heap.poll(); tail.next = head; tail = head; if (head.next != null) { heap.add(head.next); } } return dummy.next; } }
class Element { public int row, col, val; Element(int row, int col, int val) { this.row = row; this.col = col; this.val = val; } } public class Solution { private Comparator<Element> ElementComparator = new Comparator<Element>() { public int compare(Element left, Element right) { return left.val - right.val; } }; /** * @param arrays k sorted integer arrays * @return a sorted array */ public int[] mergekSortedArrays(int[][] arrays) { if (arrays == null) { return new int[0]; } int total_size = 0; Queue<Element> Q = new PriorityQueue<Element>( arrays.length, ElementComparator); for (int i = 0; i < arrays.length; i++) { if (arrays[i].length > 0) { Element elem = new Element(i, 0, arrays[i][0]); Q.add(elem); total_size += arrays[i].length; } } int[] result = new int[total_size]; int index = 0; while (!Q.isEmpty()) { Element elem = Q.poll(); result[index++] = elem.val; if (elem.col + 1 < arrays[elem.row].length) { elem.col += 1; elem.val = arrays[elem.row][elem.col]; Q.add(elem); } } return result; } }
以上是关于合并k个排序链表的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode练习(Python):链表类:第23题:合并K个排序链表:合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。