目录
https://leetcode.com/problems/merge-k-sorted-lists/
将k个有序链表合并成一个有序链表后返回
一、问题分析
测试用例:
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
二、代码实现
1、将第一个链表之外的所有链表分别与第一个链表合并
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) { //[]
return null;
}
ListNode first = lists[0];
for (int i = 1; i<lists.length; i++) {
first = mergeTwoLists(first, lists[i]);
}
return first;
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode tempHead = new ListNode(-1);
ListNode tempTail = tempHead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
tempTail.next = l1;
l1 = l1.next;
tempTail = tempTail.next;
} else {
tempTail.next = l2;
l2 = l2.next;
tempTail = tempTail.next;
}
}
if (l1 != null) {
tempTail.next = l1;
}
if (l2 != null) {
tempTail.next = l2;
}
// return tempHead.next;
ListNode temp = tempHead;
tempHead = tempHead.next;
temp.next = null;
return tempHead;
}
}
2、采用类似归并排序迭代版本自底向上的写法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) { //[]
return null;
}
int step = 1; //2*step的下标跨度作为一个小组,将小组的两个链表合并
while (step < lists.length) {
for (int i=0; i<lists.length; i += 2*step) {
if (i+step >= lists.length) {
// mergeTwoLists(lists[i], null);
// [[],[1]] 输出[]
lists[i] = mergeTwoLists(lists[i], null);
} else {
// mergeTwoLists(lists[i], lists[i+step]);
// [[],[1]] 输出[]
lists[i] = mergeTwoLists(lists[i], lists[i+step]);
}
// step = 2 * step;
// [[],[-1,5,11],[],[6,10]] 输出[-1,5,11]
}
step = step * 2;
}
return lists[0];
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//[[], [1]] 输出[]
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode tempHead = new ListNode(-1);
ListNode tempTail = tempHead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
tempTail.next = l1;
l1 = l1.next;
tempTail = tempTail.next;
} else {
tempTail.next = l2;
l2 = l2.next;
tempTail = tempTail.next;
}
}
if (l1 != null) {
tempTail.next = l1;
}
if (l2 != null) {
tempTail.next = l2;
}
// return tempHead.next;
ListNode temp = tempHead;
tempHead = tempHead.next;
temp.next = null;
return tempHead;
}
}
3、小顶堆
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
//小顶堆
Queue<ListNode> heap = new PriorityQueue(new Comparator<ListNode>(){
@Override public int compare(ListNode l1, ListNode l2) {
return l1.val - l2.val;
}
});
//Queue<ListNode> heap = new PriorityQueue<>((l1, l2) -> l1.val - l2.val);
//Queue<ListNode> heap = new PriorityQueue<>(lists.length, (l1,l2) -> Integer.compare(l1.val, l2.val));
ListNode head = new ListNode(0), tail = head;
for (ListNode node : lists) {
if (node != null) {
heap.offer(node);
}
}
while (!heap.isEmpty()) {
tail.next = heap.poll();
tail = tail.next;
if (tail.next != null) {
heap.offer(tail.next);
}
}
return head.next;
}
}
参考:
https://leetcode.com/problems/merge-k-sorted-lists/discuss/10809/13-lines-in-Java
https://leetcode.com/problems/merge-k-sorted-lists/discuss/10640/Simple-Java-Merge-Sort