合并 K 个升序链表
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 52 ms, 内存: 18.6 MB
/*
思路:
使用流式处理方法,将所有链表节点收集到一个列表中,然后排序,最后重新构建链表。
*/
import java.util.*;
import java.util.stream.*;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class MergeKSortedListsStream {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
List<ListNode> nodeList = Arrays.stream(lists)
.filter(Objects::nonNull)
.flatMap(list -> {
List<ListNode> nodes = new ArrayList<>();
while (list != null) {
nodes.add(list);
list = list.next;
}
return nodes.stream();
})
.sorted(Comparator.comparingInt(n -> n.val))
.collect(Collectors.toList());
ListNode dummy = new ListNode(0);
ListNode current = dummy;
for (ListNode node : nodeList) {
current.next = node;
current = current.next;
}
current.next = null;
return dummy.next;
}
}
解释
方法:
这个题解采用了分治法的思想,将合并 k 个链表的问题分解为合并两个链表的问题。具体做法是:
1. 如果链表数组长度为 1,直接返回该链表。
2. 如果链表数组长度大于 1,将其分为两半,分别对这两半递归地进行合并。
3. 合并两个链表的过程中,使用一个虚拟头节点,依次比较两个链表的节点值,将较小的节点接到结果链表上,直到其中一个链表为空,再将另一个链表剩余部分接到结果链表上。
时间复杂度:
O(kn * log(k))
空间复杂度:
O(log(k))
代码细节讲解
🦆
在实现分治法合并链表的过程中,为什么选择递归而不是迭代?递归方法是否对内存和性能有特定的影响?
▷🦆
对于输入链表数组为空(`lists = []`)或全部链表为空(`lists = [[]]`)的情况,解决方案是否有特殊处理?如果没有,如何改进代码以更优雅地处理这些边界情况?
▷🦆
递归函数`merge_list`在处理`l > r`的情况时直接返回`None`,这是否会影响合并的最终结果,尤其是在某些子数组为空的情况下?
▷