题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
来源:力扣(LeetCode)https://leetcode-cn.com/problems/merge-k-sorted-lists
思路
暴力法
看到这个题熟悉Java基本类库的同学,第一时间会想到,遍历链表,用个List存起来,然后用Collections.sort排个序,然后再遍历这个List生成链表。本以为会超时,居然过了,真开心。
private ListNode merge(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
List<Integer> all = new ArrayList<>();
for (ListNode list : lists) {
ListNode node = list;
while (node != null) {
all.add(node.val);
node = node.next;
}
}
Collections.sort(all);
if (all.isEmpty()) {
return null;
}
ListNode head = new ListNode(all.get(0));
ListNode temp = head;
for (int i = 1; i < all.size(); i++) {
temp.next = new ListNode(all.get(i));
temp = temp.next;
}
return head;
}
两两合并
想到两两合并是因为之前做过一个两个链表的合并的题目,所以可以抄过来,加个循环即可,两个链表合并分治算法,递归搞的。就是将两个链表逐一向后遍历,左边的小就挪左边的,右边的小就挪右边的。
private ListNode merge1(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
if (lists.length == 1) {
return lists[0];
}
ListNode res = lists[0];
for (int i = 1; i < lists.length; i++) {
res = mergeTwoList(res, lists[i]);
}
return res;
}
private ListNode mergeTwoList(ListNode left, ListNode right) {
if (left == null) {
return right;
} else if (right == null) {
return left;
} else if (left.val < right.val) {
left.next = mergeTwoList(left.next, right);
return left;
} else {
right.next = mergeTwoList(left, right.next);
return right;
}
}