内容目录
LeetCode23:合并K个升序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表
一、解题思路
1、思路1
可以遍历链表集合中的数据,不断地取出两个链表进行两个两个链表的合并,合并方法就是LeetCode20:合并两个有序链表
2、思路2
思路1的方法造成了较大的复杂度,不用顺序合并是否也能完成K个链表的合并???
可以进行分治合并,就是每次都将两个进行合并,然后再将结果两两合并,直到返回一个结果
具体步骤如下所示
3、思路3
优先队列解题
我们假设有一个队列,这个队列保存了k个链表的head元素,那么队列中最多就会有k个元素
我们需要创建一个类,用于存放每个链表的状态State(val, head)
然后使用优先队列,将列表中的k个链表放到队列中,每次取出一个,放到结果链表中,然后判断该取出的链表next是否还有数据
如果有,再次加入队列。
注意:优先队列会按照我们的排序方式进行排序加入队列
PriorityQueue<Status> queue = new PriorityQueue<Status>();
java提供队列的使用方法
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞
二、代码实现
合并两个有序链表的方法
public ListNode mergerTwo(ListNode l1, ListNode l2){
if(l1 == null) return l2;
if(l2 == null) return l1;
if(l1.val < l2.val){
l1.next = mergerTwo(l1.next, l2);
return l1;
}else{
l2.next = mergerTwo(l1, l2.next);
return l2;
}
}
1、解法1
public ListNode mergeKLists(ListNode[] lists) {
int s = lists.length;
if(s == 0) return null;
if(s == 1) return lists[0];
ListNode res = lists[0];
for(int i = 1; i < s; i++){
res = mergerTwo(res, lists[i]);
}
return res;
}
2、解法2
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
return merge(lists, 0, lists.length - 1);
}
public ListNode merge(ListNode[] lists, int l, int r) {
if (l == r) {
return lists[l];
}
if (l > r) {
return null;
}
int mid = (l + r) >> 1;
return mergeTwo(merge(lists, l, mid), merge(lists, mid + 1, r));
}
}
3、解法3
class Solution {
class Status implements Comparable<Status> {
int val;
ListNode ptr;
Status(int val, ListNode ptr) {
this.val = val;
this.ptr = ptr;
}
public int compareTo(Status status2) {
return this.val - status2.val;
}
}
PriorityQueue<Status> queue = new PriorityQueue<Status>();
public ListNode mergeKLists(ListNode[] lists) {
for (ListNode node: lists) {
if (node != null) {
queue.offer(new Status(node.val, node));
}
}
ListNode head = new ListNode(0);
ListNode tail = head;
while (!queue.isEmpty()) {
Status f = queue.poll();
tail.next = f.ptr;
tail = tail.next;
if (f.ptr.next != null) {
queue.offer(new Status(f.ptr.next.val, f.ptr.next));
}
}
return head.next;
}
}