zoukankan      html  css  js  c++  java
  • 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     }

    运行结果:

    方法一的运行结果:

    方法二的运行结果:

  • 相关阅读:
    1833: [ZJOI2010]count 数字计数——数位dp
    【模板】BZOJ 3685: 普通van Emde Boas树——Treap
    【模板】解决二分图匹配的强力算法——Hopcroft-Karp算法
    BZOJ 4516: [Sdoi2016]生成魔咒——后缀数组、并查集
    【模板】二分图匹配/一般图匹配——匈牙利算法/随机匈牙利算法
    【模板】BZOJ 1692:队列变换—后缀数组 Suffix Array
    BZOJ 4241: 历史研究——莫队 二叉堆
    【模板】BZOJ 3781: 小B的询问 莫队算法
    BZOJ 3656: 异或 (组合数取模 CRT)
    【模板】SPOJ FACT0 大数分解 miller-rabin & pollard-rho
  • 原文地址:https://www.cnblogs.com/BaoZiY/p/10685178.html
Copyright © 2011-2022 走看看