Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
这道题目一开始就弄错了思路,虽然参照了之前 LeetCode_OJ【21】Merge Two Sorted Lists 的思路来解题,却使用了错误的使用方法。
错误的使用方法:对于所有给定的头结点,比较每个头结点大小,将最小的那个添加到新链,所有的链表遍历完后算法结束。
这个方法自然是在某些比较暴力的用例上超时。
但是我不死心,开始着手改进,对于所有链表,先根据其头结点的val值排好序,新链直接选取序列中第一个链表的头结点,然后再根据该链表接下来的节点的val在list中的找好位置,进入下个循环。
结果还是超时。
然后我上网搜了下,发现直接将lists中的链表利用 LeetCode_OJ【21】Merge Two Sorted Lists 的方法依次合二为一即可。于是写下了下面的代码
public class solution{
public ListNode mergeKLists(ListNode[] lists) {
ListNode p = null;
if(lists.length > 0){
p = lists[0];
}
for(int i = 1 ; i < lists.length ; i ++){
p = mergeTwoLists(p,lists[i]);
}
return p;
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1);
ListNode p = dummy;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
p.next = l1;
l1 = l1.next;
p = p.next;
}
else{
p.next = l2;
l2 = l2.next;
p = p.next;
}
}
if(l1 != null){
p.next = l1;
}
else{
p.next = l2;
}
return dummy.next;
}
}
提交了以后以差一点就超时的性能AC了,我以为是leetcode服务器大姨妈,直接祭出重复提交大法,结果都是超时。。。。我的内心是崩溃的
然后我发现了这个:http://www.tuicool.com/articles/ZnuEVfJ
通过采用二次归并排序的思想,代码变成了下面这个:
public class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists ==null || lists.length == 0){
return null;
}
return div(lists,0,lists.length-1);
}
public ListNode div(ListNode[] lists,int l,int r){
if(l < r){
int m = (l + r)/2;
return mergeTwoLists(div(lists,l,m),div(lists,m+1,r));
}
return lists[l];
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1);
ListNode p = dummy;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
p.next = l1;
l1 = l1.next;
p = p.next;
}
else{
p.next = l2;
l2 = l2.next;
p = p.next;
}
}
if(l1 != null){
p.next = l1;
}
else{
p.next = l2;
}
return dummy.next;
}
}
性能得到了比较大的提升。