合并k个已排序的链表---困难

简介: 合并k个已排序的链表---困难

题目描述:


合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。


范围:


节点总数>=0  、链表个数 >= 1 、 链表长度 >= 1


示例1:


输入:[{1,2,3},{4,5,6,7}]


返回值:{1,2,3,4,5,6,7}


示例2:


输入:[{1,2},{1,4,5},{6}]


返回值:{1,1,2,4,5,6}


初始代码:

import java.util.*;
public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
    }
}

解决思路:


1、先写一个功能函数merge,能够将两个有序链表合并成一个有序链表

2、按照顺序 一个个合并每一个链表!


失误点:时间复杂度过高!代码运算超时!


如何解决:  利用归并的思想!


  • step 1:从链表数组的首和尾开始,每次划分从中间开始划分,划分成两半,得到左边n/2个链表和右边n/2个链表。
  • step 2:继续不断递归划分,直到每部分链表数为1.
  • step 3:将划分好的相邻两部分链表,按照两个链表合并的方式合并,合并好的两部分继续往上合并,直到最终合并成一个链表。
import java.util.*;
public class Solution {
    private ListNode merge(ListNode list1, ListNode list2) {
        if (list1 == null && list2 == null) {
            return null;
        } else if (list1 != null && list2 == null) {
            return list1;
        } else if (list1 == null) {
            return list2;
        }
        ListNode ret = new ListNode(0);
        ListNode cur = ret;
        while (list1 != null && list2 != null) {
            if (list1.val <= list2.val) {
                ListNode node = new ListNode(list1.val);
                cur.next = node;
                list1 = list1.next;
            } else {
                ListNode node = new ListNode(list2.val);
                cur.next = node;
                list2 = list2.next;
            }
            cur = cur.next;
        }
        if (list1 == null) {
            cur.next = list2;
        } else {
            cur.next = list1;
        }
        return ret.next;
    }
//!!时间超时的原本代码
    //    public ListNode mergeKLists(ArrayList<ListNode> lists) {
//        if (lists.isEmpty()){
//            return null;
//        }
//        ListNode[] arr = new ListNode[lists.size()];
//        lists.toArray(arr);
//        int index = arr.length;
//        ListNode ret = merge(arr[index-1],arr[index-2]);
//        index-=3;
//        while(index>=0){
//            ret=merge(ret,arr[index]);
//            index--;
//        }
//        return ret;
//    }
//下面是改进后的代码
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        ListNode[] arr = new ListNode[lists.size()];
        lists.toArray(arr);
        return merge1(arr, 0, arr.length - 1);
    }
    private ListNode merge1(ListNode[] arr, int left, int right) {
        if (left>right){
            return null;
        }else if (left==right){
            return arr[left];
        }
        int mid = (left+right)/2;
//重点要读懂这一句!!
        return merge(merge1(arr,left,mid),merge1(arr,mid+1,right));
    }
}


相关文章
|
6天前
《剑指offer》——合并两个排序的链表
《剑指offer》——合并两个排序的链表
|
6天前
|
Java C语言
剑指offer(牛客)——合并两个排序的链表
剑指offer(牛客)——合并两个排序的链表
9 1
|
6天前
【力扣】148. 排序链表
【力扣】148. 排序链表
|
6天前
【力扣】83. 删除排序链表中的重复元素、82. 删除排序链表中的重复元素Ⅱ
【力扣】83. 删除排序链表中的重复元素、82. 删除排序链表中的重复元素Ⅱ
|
6天前
|
存储 JavaScript
leetcode82. 删除排序链表中的重复元素 II
leetcode82. 删除排序链表中的重复元素 II
25 0
|
6天前
leetcode83. 删除排序链表中的重复元素
leetcode83. 删除排序链表中的重复元素
12 0
|
6天前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
|
6天前
|
存储
LeetCode刷题---817. 链表组件(哈希表)
LeetCode刷题---817. 链表组件(哈希表)
|
6天前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
6天前
|
算法 安全 数据处理
LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)
LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)