lintcode -合并k个排序链表
2017-07-17 09:00
253 查看
合并k个排序链表,并且返回合并后的排序链表。尝试分析和描述其复杂度。
您在真实的面试中是否遇到过这个题?
Yes
样例
给出3个排序链表[2->4->null,null,-1->null],返回 -1->2->4->null
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
思路:
分治法
* 简单来说就是不停的对半划分,
* 比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,开始合并。
* 举个例子来说比如合并6个链表,那么按照分治法,我们首先分别合并1和4,2和5,3和6。这样下一次只需合并3个链表,我们再合并1和3,最后和2合并就可以了
*
*
* 类似于归并排序的思想,lists中存放的是多个单链表,将lists的头和尾两个链表合并,放在头,头向后移动,尾向前移动,继续合并,直到头和尾相等,此时已经归并了一半, 然后以同样的方法又重新开始归并剩下的一半。时间复杂度是O(logn),合并两个链表的时间复杂度是O(n),则总的时间复杂度大概是O(nlogn);
*/
//分治法
public class Solution {
public ListNode mergeKLists(List<ListNode> lists) {
if (lists.size() == 0) {
return null;
}
return mergeHelper(lists, 0, lists.size() - 1);
}
private ListNode mergeHelper(List<ListNode> lists, int start, int end) {
if (start == end) {
return lists.get(start);
}
int mid = (end +start) / 2;
ListNode left = mergeHelper(lists, start, mid);//不断划分
ListNode right = mergeHelper(lists, mid + 1, end);
return mergeTwoLists(left, right);
}
private ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
tail.next = list1;
list1 = list1.next;
} else {
tail.next = list2;
list2 = list2.next;
}
tail = tail.next;
}
if (list1 != null) {
tail.next = list1;
} else {
tail.next = list2;
}
return dummy.next;
}
}
/*
按照前面实现的合并两个排序的链表的方法,两两合并,如果是奇数个,最后记得再合并最后一个即可。
*/
您在真实的面试中是否遇到过这个题?
Yes
样例
给出3个排序链表[2->4->null,null,-1->null],返回 -1->2->4->null
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
思路:
分治法
* 简单来说就是不停的对半划分,
* 比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,开始合并。
* 举个例子来说比如合并6个链表,那么按照分治法,我们首先分别合并1和4,2和5,3和6。这样下一次只需合并3个链表,我们再合并1和3,最后和2合并就可以了
*
*
* 类似于归并排序的思想,lists中存放的是多个单链表,将lists的头和尾两个链表合并,放在头,头向后移动,尾向前移动,继续合并,直到头和尾相等,此时已经归并了一半, 然后以同样的方法又重新开始归并剩下的一半。时间复杂度是O(logn),合并两个链表的时间复杂度是O(n),则总的时间复杂度大概是O(nlogn);
*/
//分治法
public class Solution {
public ListNode mergeKLists(List<ListNode> lists) {
if (lists.size() == 0) {
return null;
}
return mergeHelper(lists, 0, lists.size() - 1);
}
private ListNode mergeHelper(List<ListNode> lists, int start, int end) {
if (start == end) {
return lists.get(start);
}
int mid = (end +start) / 2;
ListNode left = mergeHelper(lists, start, mid);//不断划分
ListNode right = mergeHelper(lists, mid + 1, end);
return mergeTwoLists(left, right);
}
private ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
tail.next = list1;
list1 = list1.next;
} else {
tail.next = list2;
list2 = list2.next;
}
tail = tail.next;
}
if (list1 != null) {
tail.next = list1;
} else {
tail.next = list2;
}
return dummy.next;
}
}
/*
按照前面实现的合并两个排序的链表的方法,两两合并,如果是奇数个,最后记得再合并最后一个即可。
*/
相关文章推荐
- LintCode-分治-合并k个排序链表
- lintcode-104-合并k个排序链表
- lintcode 合并k个排序链表
- lintcode-合并k个排序链表-104
- 合并k个排序链表-LintCode
- lintcode--合并k个排序链表
- 合并k个排序链表,lintcode
- [LintCode 104] 合并k个排序链表(Python)
- LeetCode-Merge k Sorted Lists-合并k个排序链表-自底向上归并排序+链表操作
- LeetCodet题解--23. Merge k Sorted Lists(合并K个已排序的链表)
- 104. 合并k个排序链表
- 合并k个排序链表
- “用最小堆将k个已排序链表合并为一个排序链表”(算法导论 练习6.5-9)
- Google/LintCode:M-合并k个排序链表
- 合并k个排序链表
- [LintCode]165.合并两个排序链表
- LintCode_165_合并两个排序链表
- LintCode -合并两个排序链表
- leetcode 23. Merge k Sorted Lists 合并k个排序链表 优先级队列
- 用最小堆将k个已排序链表合并为一个排序链表