Leetcode 23. 合并K个排序链表
题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
题目解析
类似合并两个有序链表,但是由于数组长度不确定,使用递归有点麻烦。
第一次
暴力实现,验证猜想和算法思路。将每一个链表比较成功后指向 next。注意哑节点思路不需要判空。
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
ListNode root = new ListNode(-1);
ListNode node = root;
while(true) {
int minIndex = -1;
for (int i = 0; i < lists.length; i++) {
if (lists[i] != null) {
if (minIndex == -1) {
minIndex = i;
} else {
if (lists[i].val < lists[minIndex].val) minIndex = i;
}
}
}
if (minIndex == -1) break;
ListNode temp = lists[minIndex];
lists[minIndex] = temp.next;
node.next = temp;
node = node.next;
}
return root.next;
}
}
第二次
使用 TreeMap 有序的特性,实现方式局限性比较大,空间复杂度较高(可以进行部分优化)主要理解其算法思路。
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
Map<Integer, Integer> results = new TreeMap<>();
for (int i = 0; i < lists.length; i++) {
ListNode node = lists[i];
while(node != null) {
int count = results.getOrDefault(node.val, 0);
results.put(node.val, ++count);
node = node.next;
}
}
ListNode root = new ListNode(-1);
ListNode node = root;
for (Map.Entry<Integer, Integer> entry : results.entrySet()) {
for (int i = 0; i < entry.getValue(); i++) {
node.next = new ListNode(entry.getKey());
node = node.next;
}
}
return root.next;
}
}
第三次
使用优先级队列
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
ListNode root = new ListNode(-1);
PriorityQueue<ListNode> pq = new PriorityQueue<>((o1, o2) -> {
return o1.val - o2.val;
});
for (ListNode linked : lists) {
if (linked == null) continue;
pq.add(linked);
}
ListNode node = root;
while(!pq.isEmpty()) {
ListNode poll = pq.poll();
node.next = poll;
node = node.next;
if (poll.next != null) pq.add(poll.next);
}
return root.next;
}
}
第四次
AC 递归,分解,合并 = 归并
class Solution {
public ListNode mergeKLists(ListNode[] lists){
if(lists.length == 0) return null;
if(lists.length == 1) return lists[0];
if(lists.length == 2) return mergeTwoLists(lists[0],lists[1]);
int mid = lists.length/2;
ListNode[] l1 = new ListNode[mid];
for(int i = 0; i < mid; i++) l1[i] = lists[i];
ListNode[] l2 = new ListNode[lists.length-mid];
for(int i = mid,j=0; i < lists.length; i++,j++) l2[j] = lists[i];
return mergeTwoLists(mergeKLists(l1),mergeKLists(l2));
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode head = null;
if (l1.val <= l2.val){
head = l1;
head.next = mergeTwoLists(l1.next, l2);
} else {
head = l2;
head.next = mergeTwoLists(l1, l2.next);
}
return head;
}
}
浙公网安备 33010602011771号