1.算法题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
2.算法思路
算法思路:
- 暴力法:每次遍历 n 个链表查找最小的值放入链表指定位置,算法复杂度是 O(kN),其中 N 是总共节点的数量;
- 分治法:两两比较临近的链表,第一轮比较过后合并成 k/2 个有序链表,第二轮比较后合并成 k/4 个有序链表,...;重复这一过程,直到剩余最后一个有序链表,即为符合题意的最终链表,算法复杂度 O(Nlogk)
3.算法代码
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
int len = lists.length;
int step = 1;
while (step < len) {
for (int i = 0; i < len - step; i = i + 2*step) {
lists[i] = mergeTwoLists(lists[i], lists[i + step]);
}
step *= 2;
}
return lists[0];
}
// 合并两个有序链表:算法复杂度 O(n),其中 n 为两个链表节点的总数量
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prevHead = new ListNode(-1);
ListNode prev = prevHead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
prev.next = l1;
l1 = l1.next;
} else {
prev.next = l2;
l2 = l2.next;
}
prev = prev.next;
}
prev.next = l1 != null ? l1 : l2;
return prevHead.next;
}
如果你有疑问或更好的算法思路,欢迎留言交流!!!
如果感觉我的文章对您有所帮助,麻烦动动小手给个喜欢,谢谢!!!