zoukankan      html  css  js  c++  java
  • No.023:Merge k Sorted Lists

    问题:

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

    官方难度:

    Hard

    翻译:

    合并k个已排序的链表,得到一个新的链表并且返回其第一个节点。分析并阐述其复杂度。

    1. 这是No.021(Merge Two Sorted Lists)的深入研究。
    2. 可以借鉴归并排序的思想,对于长度为k的数组,依次进行二路归并,返回这两个链表合并之后的头结点(利用No.021现成的代码),下次递归时,入参为长度为(k+1)/2的头结点数组。
    3. 在k为奇数时,先去掉最后一项,剩余项依次二路归并,再将最后一项放入新的数组。
    4. 由于使用递归,所以将递归方法独立出来,因为只要做依次入参检查即可。
    5. 算法的复杂度与归并排序相同,即O(nlogn)的时间复杂度,O(n)的空间复杂度。

    解题代码:

     1     public static ListNode mergeKLists(ListNode[] lists) {
     2         if (lists == null) {
     3             throw new IllegalArgumentException("Input error");
     4         }
     5         if (lists.length == 0) {
     6             return null;
     7         }
     8         return mergeListsArray(lists);
     9     }
    10 
    11     // 合并 k 个有序链表
    12     public static ListNode mergeListsArray(ListNode[] lists) {
    13         // 递归终点
    14         if (lists.length == 1) {
    15             return lists[0];
    16         }
    17         // 下一次递归的头结点数组
    18         ListNode[] next = new ListNode[(lists.length + 1) >>> 1];
    19         // 二路归并
    20         if (lists.length % 2 == 0) {
    21             for (int i = 0; i < lists.length; i += 2) {
    22                 next[i >>> 1] = merge2Lists(lists[i], lists[i + 1]);
    23             }
    24         } else {
    25             for (int i = 0; i < lists.length - 1; i += 2) {
    26                 next[i >>> 1] = merge2Lists(lists[i], lists[i + 1]);
    27             }
    28             next[next.length - 1] = lists[lists.length - 1];
    29         }
    30         return mergeListsArray(next);
    31     }
    32 
    33     // 合并2个有序链表
    34     private static ListNode merge2Lists(ListNode l1, ListNode l2) {
    35         if (l1 == null) {
    36             return l2;
    37         }
    38         if (l2 == null) {
    39             return l1;
    40         }
    41         // 返回的第一个节点
    42         ListNode first = l1.val > l2.val ? l2 : l1;
    43         // 上一个节点
    44         ListNode last = new ListNode(0);
    45         while (true) {
    46             if (l1.val > l2.val) {
    47                 // 交换l1节点和l2节点,保证下一次循环仍然以l1节点为基准
    48                 ListNode swapNode = l2;
    49                 l2 = l1;
    50                 l1 = swapNode;
    51             }
    52             // 将last节点的next指针指向l1,同时更新last
    53             last.next = l1;
    54             last = l1;
    55             // 带排序的链表遍历完成,剩余链表自然有序
    56             if (l1.next == null) {
    57                 l1.next = l2;
    58                 break;
    59             }
    60             l1 = l1.next;
    61         }
    62         return first;
    63     }
    mergeKLists

    相关链接:

    https://leetcode.com/problems/merge-k-sorted-lists/

    https://github.com/Gerrard-Feng/LeetCode/blob/master/LeetCode/src/com/gerrard/algorithm/hard/Q023.java

    PS:如有不正确或提高效率的方法,欢迎留言,谢谢!

  • 相关阅读:
    MyBatis原理分析
    oracle修改数据遇到的坑
    oracle查询时遇到的坑
    maven镜像
    易错题
    binlog2sql 安装使用
    Archery SQL审核平台搭建
    Docker安装
    夜莺n9e监控搭建
    influxdb安装
  • 原文地址:https://www.cnblogs.com/jing-an-feng-shao/p/6170348.html
Copyright © 2011-2022 走看看