zoukankan      html  css  js  c++  java
  • LeetCode(23) - Merge k Sorted Lists

      题目和LeetCode(21)里merge two sorted List要求差不多,现在只是从2两个list变成了k个list。

      看到这个题,第一个反应是用一个heap(最大堆)把k个list里面的数存起来,然后一个一个poll出来生成一个新的list。遍历所有list要O(n),再堆里面插入元素,需要O(log(n))的时间,再生成新的List需要O(n),所以平均时间为O(nlog(n) + n),

      代码如下:

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode mergeKLists(ListNode[] lists) {
    11         ListNode dumpNode = new ListNode(0);
    12         Queue<Integer> heap = new PriorityQueue<Integer>();
    13         //把所有元素都放到heap里面。
    14         for (ListNode head : lists) {
    15             while (head != null) {
    16                 heap.offer(head.val);
    17                 head = head.next;
    18             }
    19         }
    20         ListNode curr = dumpNode;
    21         //生成新的list
    22         while (!heap.isEmpty()) {
    23             curr.next = new ListNode(heap.poll());
    24             curr = curr.next;
    25         }
    26         return dumpNode.next;
    27     }   
    28 }

      这样做其实非常简单,但是鉴于这道题是一道hard的题,我估计这样做并不能够得到面试官的认可。首先,它并没有利用到每个list sorted的这一个性质,第二个,时间上也可以有更快的方法。

      怎么做呢?那就是利用了归并排序的特点,divide and conquer(分治)。首先是把相邻的两个list两两配对,利用LeetCode 21 merge two sorted list的方法,分别把它们merge起来,然后继续两两配对,知道merge到一个list为止。

      代码如下:

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode mergeKLists(ListNode[] lists) {
    11         ListNode res = mergeKListsHelper(lists,0,lists.length - 1);
    12         return res;
    13     }
    14     
    15     private ListNode mergeKListsHelper(ListNode[] lists, int left, int right) {
    16         //返回条件的三种情况。
    17         if (left > right) return null;
    18         //没有配对上的list
    19         if (left == right) return lists[left];
    20         //当left和right相差一个时,把它们merge起来。
    21         if (left + 1 == right) return mergeSortedList(lists[left],lists[right]);
    22         //分治,对于每一堆list,中间分开,左右各自合并,最后再merge
    23         int mid = (left + right) / 2;
    24         ListNode leftNode = mergeKListsHelper(lists, left, mid-1);
    25         ListNode rightNode = mergeKListsHelper(lists, mid, right);
    26         return mergeSortedList(leftNode, rightNode);
    27     }
    28     
    29     //merge两个list。和Leetcode 21一样。
    30     private ListNode mergeSortedList(ListNode l1, ListNode l2) {
    31         ListNode dumpNode = new ListNode(0);
    32         ListNode curr = dumpNode;
    33         while (l1 != null && l2 != null) {
    34             if (l1.val < l2.val) {
    35                 curr.next = new ListNode(l1.val);
    36                 l1 = l1.next;
    37             }
    38             else {
    39                 curr.next = new ListNode(l2.val);
    40                 l2 = l2.next;
    41             }
    42             curr = curr.next;
    43         }
    44         
    45         while (l1 != null) {
    46             curr.next = new ListNode(l1.val);
    47             l1 = l1.next;
    48             curr = curr.next;
    49         }
    50         
    51         while (l2 != null) {
    52             curr.next = new ListNode(l2.val);
    53             l2 = l2.next;
    54             curr = curr.next;
    55         }
    56         
    57         return dumpNode.next;
    58     }
    59 }
  • 相关阅读:
    .NET XmlNavigator with Namespace
    编程要素
    【FOJ】1962 新击鼓传花游戏
    【POJ】1389 Area of Simple Polygons
    【POJ】2482 Stars in Your Window
    【HDU】3265 Posters
    【HDU】1199 Color the Ball
    【HDU】3642 Get The Treasury
    【HDU】4027 Can you answer these queries?
    【HDU】1542 Atlantis
  • 原文地址:https://www.cnblogs.com/kepuCS/p/5278633.html
Copyright © 2011-2022 走看看