标签:des style blog http color os
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
这道题,第一次刷是过了,第二次同样的代码超时了,看来case是在不断加强的
算法
思路1:
最土的算法,两个月前能过,现在TLE,同[leetcode]Merge Two Sorted Lists,
首先把l1和l2合并到l1中,遍历2n个节点
再把合并之后的l1和l3合并到l1中,遍历3n个节点
再把合并之后的l1和l4合并到l1中,遍历4n个节点
....
最后把合并后的l1和lm合并到l1中,遍历m*n个节点
总共遍历了(2+3+...+m)*n个节点,时间复杂度为O(n*m^2)
代码如下:
1 public ListNode mergeKLists(List<ListNode> lists) { 2 if(lists == null || lists.size() == 0) return null; 3 ListNode l1 = lists.get(0); 4 for(int i = 1; i < lists.size(); i++) 5 l1 = mergeTwoLists(l1,lists.get(i)); 6 return l1; 7 } 8 public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 9 if(l1 == null) return l2; 10 if(l2 == null) return l1; 11 ListNode head = new ListNode(1); 12 head.next = l1; 13 ListNode pre = head; 14 ListNode node = l2; 15 while(l2 != null){ 16 node = l2; 17 while(pre.next != null && pre.next.val <= node.val){ 18 pre = pre.next; 19 } 20 l2 = node.next; 21 node.next = pre.next; 22 pre.next = node; 23 pre = node; 24 } 25 return head.next; 26 }
思路2:
分治法,将m个list分成两拨list1,list2,对每一拨分别处理
当list.size() = 1时,直接返回, size() = 2时候,即:merge2ListNode
处理完list1 和list2之后,再把二者合并
时间负责度O(n*klogk)【其中k为list.size()】
代码如下:
1 public class Solution { 2 public ListNode mergeKLists(List<ListNode> lists) { 3 if(lists == null || lists.size() == 0) return null; 4 if(lists.size() == 1) return lists.get(0); 5 if(lists.size() == 2){ 6 return merge2List(lists.get(0), lists.get(1)); 7 } 8 List<ListNode> l1 = new ArrayList<ListNode>(); 9 List<ListNode> l2 = new ArrayList<ListNode>(); 10 for(int i = 0;i < lists.size() ; i++){ 11 if(i < lists.size() / 2) l1.add(lists.get(i)); 12 else l2.add(lists.get(i)); 13 } 14 ListNode list1 = mergeKLists(l1); 15 ListNode list2 = mergeKLists(l2); 16 return merge2List(list1, list2); 17 } 18 private ListNode merge2List(ListNode l1,ListNode l2){ 19 ListNode head = new ListNode(1); 20 head.next = l1; 21 ListNode pre = head; 22 ListNode node = l2; 23 while(l2 != null){ 24 node = l2; 25 while(pre.next != null && pre.next.val <= node.val){ 26 pre = pre.next; 27 } 28 l2 = node.next; 29 node.next = pre.next; 30 pre.next = node; 31 pre = node; 32 } 33 return head.next; 34 } 35 }
思路3:
堆,由于对堆不熟悉,所以写出来的代码很丑,不过好歹AC了,时间复杂度同分治法,明天过来再优化一下:
渣代码如下:
1 public class Solution { 2 public ListNode mergeKLists(List<ListNode> lists) { 3 if(lists == null || lists.size() == 0) return null; 4 int k = 0; 5 List<ListNode> list = new ArrayList<ListNode>(); 6 for(int i = 0; i < lists.size(); i++){ 7 if(lists.get(i) != null) { 8 k++; 9 list.add(lists.get(i)); 10 } 11 } 12 if(k == 0) return null; 13 if(k == 1) return list.get(0); 14 ListNode[] heap = new ListNode[k]; 15 for(int i = 0 ; i < k ; heap[i] = list.get(i),i++); 16 for(int i = k / 2 - 1; i >= 0; i--){ 17 adjustHeap(heap, k, i); 18 } 19 ListNode result = new ListNode(0); 20 ListNode tail = result; 21 while(true){ 22 if(heap[0] == null){ 23 heap[0] = heap[k - 1]; 24 k--; 25 } 26 adjustHeap(heap, k, 0); 27 tail.next = heap[0]; 28 if(k == 0) break; 29 heap[0] = heap[0].next; 30 tail = tail.next; 31 } 32 return result.next; 33 } 34 private void adjustHeap(ListNode[] heap,int size,int i){ 35 while( 2 * i + 1 < size ){ 36 ListNode left = heap[2 * i + 1]; 37 if(left == null) return; 38 if(2 * i + 2 < size){ 39 ListNode right = heap[2 * i + 2]; 40 if(right.val <= left.val && right.val < heap[i].val){ 41 ListNode tem = right; 42 heap[2 * i + 2] = heap[i]; 43 heap[i] = tem; 44 i = 2 * i + 2; 45 }else if(left.val <= right.val && left.val < heap[i].val){ 46 ListNode tem = left; 47 heap[2 * i + 1] = heap[i]; 48 heap[i] = tem; 49 i = 2 * i + 1; 50 }else return; 51 }else{ 52 if(left.val < heap[i].val){ 53 ListNode tem = left; 54 heap[2 * i + 1] = heap[i]; 55 heap[i] = tem; 56 } 57 return; 58 } 59 } 60 } 61 62 }
参考资料:
[leetcode]Merge k Sorted Lists,布布扣,bubuko.com
[leetcode]Merge k Sorted Lists
标签:des style blog http color os
原文地址:http://www.cnblogs.com/huntfor/p/3855727.html