23. 合并K个排序链表

合并 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6
 1 //方法一:使用优先级队列实现
 2 public class MergekSortedLists {
 3     private class ListNode {
 4         int val;
 5         ListNode next;
 6         ListNode(int x) {
 7             val = x;
 8         }
 9     }
10     //时间复杂度:O(n*log(k)),n为元素总个数,每一个都要遍历输出,k为链表个数,队列中元素个数为链表数(k个元素),需要对其进行小根堆调整
11     public ListNode mergeKLists(ListNode[] lists) {
12         if(lists == null) {
13             throw new IllegalArgumentException("输入参数错误");
14         }
15         PriorityQueue<ListNode> pq = new PriorityQueue<>(10, new Comparator<ListNode>() {
16             @Override
17             public int compare(ListNode l1, ListNode l2) {
18                 //构建小根堆(由PriorityQueue源码决定)
19                 if(l1.val > l2.val) {
20                     return 1;
21                 }else if(l1.val == l2.val) {
22                     return 0;
23                 }else {
24                     return -1;
25                 }
26             }            
27         });        
28         ListNode result = new ListNode(0);
29         ListNode cur = result;
30         for(ListNode node : lists) {
31             if(node != null) {
32                 pq.add(node);
33             }
34         }
35                 
36         //遍历n次,每次小根堆调整log(k)次
37         while(!pq.isEmpty()) {
38             cur.next = pq.poll();
39             cur = cur.next;    
40             if(cur.next != null) {
41                 pq.add(cur.next);
42             }
43         }
44         return result.next;
45     }
46     
47     //方法三:使用分治法实现
48     public ListNode mergKLists2(ListNode[] lists) {
49         if(lists == null || lists.length == 0) {
50             throw new IllegalArgumentException("输入参数错误");
51         }
52         return merge(lists, 0, lists.length-1);
53     }
54     public ListNode merge(ListNode[] lists, int left, int right) {
55         if(left >= right) { //此处可以为left == right
56             return lists[left];
57         }
58         int mid = left + (right - left) / 2;  //left >= mid, 因为left<right, 所以right >= mid+1
59         ListNode l1 = merge(lists, left, mid); //将链表集合一直分为单个,两两进行比较
60         ListNode l2 = merge(lists, mid+1, right);        
61         return mergeTwoListNode(l1, l2);          
62     }
63     public ListNode mergeTwoListNode(ListNode l1, ListNode l2) {
64         //将两个链表进行合并,返回的是合并后的有序链表
65         if(l1 == null) {
66             return l2;
67         }else if(l2 == null) {
68             return l1;
69         }
70         if(l1.val < l2.val) {  //若l1值小,则返回l1节点,
71             l1.next = mergeTwoListNode(l1.next, l2);
72             return l1;
73         }else {
74             l2.next = mergeTwoListNode(l1, l2.next);
75             return l2;
76         }
77     }
78 }

 

posted @ 2019-05-19 15:55  往南的小燕子  阅读(184)  评论(0编辑  收藏  举报