K个排序链表的合并(Hard)

问题来源:选自leetCode 23:合并K个排序链表

问题描述: 

题目给定信息:

不确定需要合并的链表的数目,但依然要求我们把给定的这些有序链表合并成一个链表,并且保证合并的链表依然是有序的。

问题分析:

  我们可以使用暴力合并的方法,就是不管有多少个链表,先让第一个链表和第二个链表进行合并,合并之后的结果在和第三个链表进行合并,依次进行下去直到把全部的链表全部合并成一个链表,这种方法是最简单最易想到的方法,但是时间复杂度太高了;还有一种方法是把所有链表中的节点值保存到一个数组中,然后对这个数组进行从小到大的排序,排序完成后再通过循环为每个节点值new成一个节点对象,最后再把节点节点串联起来,这样做相比暴力求解时间复杂度要低一些,但是依然不是最优的求解方法;最优的求解方法就是使用分治思想。

函数实现:

 方法一(使用数组排序的方法求解多个有序链表的合并问题):

 1 LinkedList<Integer> list = new LinkedList<>();
 2         // 循环遍历lists数组,把该数组中每一个链表中的每一个元素全部都存入list集合中
 3         for (int i = 0; i < lists.length; i++) {
 4             ListNode temp_Head = lists[i];
 5             while (temp_Head != null) {
 6                 list.add(temp_Head.val);
 7                 temp_Head = temp_Head.next;
 8             }
 9         }
10         //判断lists是否为空,如果为空则返回null,不在这里进行验证的话,Leetcode的边界检测不通过
11         if(list.size()==0){
12             return null;
13         }
14         //将list转换为数组方便使用Arrays.sort()函数进行排序
15         Integer[] array_val = list.toArray(new Integer[0]);
16         Arrays.sort(array_val);
17         ListNode[] array = new ListNode[array_val.length];
18         //将排序后的数组全部在生成对应的ListNode对象。此时的对象就已经是有序的
19         for (int i = 0; i < array_val.length; i++) {
20             array[i] = new ListNode(array_val[i]);
21         }
22         // 把ListNode[] array数组连接成一个链表
23         for (int i = 0; i < array.length - 1; i++) {
24             array[i].next = array[i + 1];
25         }
26         return array[0];
27     }

方法二(分治思想):

 1 public ListNode mergeKLists(ListNode[] lists) {
 2         if (lists.length == 0) {
 3             return null;
 4         }
 5         if (lists.length == 1) {
 6             return lists[0];
 7         }
 8         if (lists.length == 2) {
 9             return mergeTwoLists(lists[0], lists[1]);
10         }
11         int mid = lists.length / 2;
12         ListNode[] lists_sub1 = new ListNode[mid];
13         ListNode[] lists_sub2 = new ListNode[lists.length - mid + 1];
14         for(int i=0;i<mid;i++){
15             lists_sub1[i]=lists[i];
16         }
17         for(int i=mid;i<lists.length;i++){
18             lists_sub2[i]=lists[i];
19         }
20         ListNode l1=mergeKLists(lists_sub1);
21         ListNode l2=mergeKLists(lists_sub2);
22         return mergeTwoLists(l1,l2);
23     }
24 
25     public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
26         ListNode newHead = new ListNode(0);
27         ListNode temp_newHead = newHead;
28         while (l1 != null && l2 != null) {
29             if (l1.val < l2.val) {
30                 temp_newHead.next = l1;
31                 l1 = l1.next;
32             } else {
33                 temp_newHead.next = l2;
34                 l2 = l2.next;
35             }
36             temp_newHead = temp_newHead.next;
37         }
38         if (l1 != null) {
39             temp_newHead.next = l1;
40         }
41         if (l2 != null) {
42             temp_newHead.next = l2;
43         }
44         return newHead.next;
45     }

运行结果:

方法一的运行结果:

方法二的运行结果:

posted @ 2019-04-10 22:55  包子的百草园  阅读(152)  评论(0编辑  收藏  举报