思路1
借鉴合并两个升序链表的算法,两两合并。
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0)
return null;
if (lists.length == 1)
return lists[0];
ListNode tmp = mergeTwoLists(lists[0], lists[1]);
for (int i = 2; i < lists.length; i++)
{
tmp = mergeTwoLists(tmp, lists[i]);
}
return tmp;
}
private ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null)
return list2;
if (list2 == null)
return list1;
ListNode h2 = new ListNode(); // dummy node 可以将两种情况合并
h2.next = list2;
ListNode p1 = list1, p2 = list2;
ListNode preNode = h2;
while (p1 != null)
{
int val = p1.val;
ListNode rem = p1.next;
// 查找插入位置
while (p2 != null && p2.val < val)
{
preNode = p2;
p2 = p2.next;
}
if (p2 == null)
{
preNode.next = p1;
break;
}
else
{
preNode.next = p1;
p1.next = p2;
preNode = p1;
}
p1 = rem;
}
return h2.next;
}
思路2
分治算法,参考题解
public ListNode mergeKLists(ListNode[] lists) {
// if (lists.length == 0)
// return null;
// if (lists.length == 1)
// return lists[0];
// ListNode tmp = mergeTwoLists(lists[0], lists[1]);
// for (int i = 2; i < lists.length; i++)
// {
// tmp = mergeTwoLists(tmp, lists[i]);
// }
// return tmp;
return merge(lists, 0, lists.length-1);
}
private 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 mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
}
private ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null)
return list2;
if (list2 == null)
return list1;
ListNode h2 = new ListNode(); // dummy node 可以将两种情况合并
h2.next = list2;
ListNode p1 = list1, p2 = list2;
ListNode preNode = h2;
while (p1 != null)
{
int val = p1.val;
ListNode rem = p1.next;
// 查找插入位置
while (p2 != null && p2.val < val)
{
preNode = p2;
p2 = p2.next;
}
if (p2 == null)
{
preNode.next = p1;
break;
}
else
{
preNode.next = p1;
p1.next = p2;
preNode = p1;
}
p1 = rem;
}
return h2.next;
}
思路3
最小堆,参考题解
public class L23_V3 {
class Node implements Comparable<Node>
{
ListNode node;
Node(ListNode node)
{
this.node = node;
}
public int compareTo(Node node2)
{
return this.node.val - node2.node.val;
}
}
public ListNode mergeKLists(ListNode[] lists)
{
ListNode head = new ListNode();
ListNode tail = head;
PriorityQueue<Node> pq = new PriorityQueue<Node>();
for (int i = 0; i < lists.length; i++)
{
if (lists[i] != null)
pq.offer(new Node(lists[i]));
}
while (!pq.isEmpty())
{
Node minNode = pq.poll();
tail.next = minNode.node;
tail = minNode.node;
if (tail.next != null)
pq.offer(new Node(tail.next));
}
return head.next;
}
}