BM5. [合并k个已排序的链表]

alt

https://www.nowcoder.com/exam/oj?tab=%E7%AE%97%E6%B3%95%E7%AF%87&topicId=295

BM5. 合并k个已排序的链表

https://www.nowcoder.com/practice/65cfde9e5b9b4cf2b6bafa5f3ef33fa6?tpId=295&sfm=discuss&channel=nowcoder

题目分析

上一道题目你已经掌握地非常清楚了,在复用合并两个有序链表函数的基础上,给这个题目引入一个归并算法就能轻松解决这道题目。所以这道题目值得多刷几遍,感受一下归并分治的思想

做法分析

复用合并两个排序链表函数

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        //先判断两者是否为空的情况
        if(l1 == null)
            return l2;
        if(l2 == null)
            return l1;
        ListNode mergeNode = null;
        // 两个需要合并的队列都不为空的情况那需要确定头结点
        if(l1.val < l2.val){
            mergeNode = l1;
            mergeNode.next = mergeTwoLists(l1.next, l2);
        }else{
            mergeNode = l2;
            mergeNode.next = mergeTwoLists(l1, l2.next);
        }
        return mergeNode;
    }

写分解K个链表的函数,确定区间left,right,确定何时(left==right)返回归并的对象。归并函数写起来非常的简单

public ListNode mergeInternal(ArrayList<ListNode> lists, int left, int right){
        //如果区间已经闭合,返回最小的区间值
        if(left == right){
            return lists.get(left);
        }
        if(left > right){
            return null;
        }
        int mid = left + (right - left) / 2;
        // 合并两个小区间
        return mergeTwoLists(mergeInternal(lists, left, mid), mergeInternal(lists, mid + 1, right));
    }

连接主干函数,这种相对比较复杂的题目不要害怕写得函数比较多,只要确保每个函数职责明确就没有问题

public ListNode mergeKLists(ArrayList<ListNode> lists) {
    int left = 0;
    int right = lists.size() - 1;
    return mergeInternal(lists, left, right);
}

完整题解

 public ListNode mergeKLists(ArrayList<ListNode> lists) {
    int left = 0;
    int right = lists.size() - 1;
    return mergeInternal(lists, left, right);
  }

  public ListNode mergeInternal(ArrayList<ListNode> lists, int left, int right){
    if(left == right){
      return lists.get(left);
    }
    if(left > right){
      return null;
    }
    int mid = left + (right - left) / 2;
    return mergeTwoLists(mergeInternal(lists, left, mid), mergeInternal(lists, mid + 1, right));
  }

  public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    //先判断两者是否为空的情况
    if(l1 == null)
      return l2;
    if(l2 == null)
      return l1;
    ListNode mergeNode = null;
    // 两个需要合并的队列都不为空的情况那需要确定头结点
    if(l1.val < l2.val){
      mergeNode = l1;
      mergeNode.next = mergeTwoLists(l1.next, l2);
    }else{
      mergeNode = l2;
      mergeNode.next = mergeTwoLists(l1, l2.next);
    }
    return mergeNode;
  }

复杂度分析

时间复杂度:,归并排序的时间复杂度

空间复杂度:需要额外开辟空间返回链表

alt

#面经##题解##面试题目#
全部评论

相关推荐

黑皮白袜臭脚体育生:简历条例统一按使用了什么技术实现了什么功能解决了问题或提升了什么性能指标来写会好些,如使用布隆过滤器实现了判断短链接是否存在,大大提升了查询速度
点赞 评论 收藏
分享
01-23 14:54
同济大学 Java
热爱敲代码的程序媛:给你提几点【专业技能】这个模块里面可优化的地方:1.【具备JVM调优经验】可以去b站上搜一下JVM调优的视频,估计一两个小时凭你的学习能力就能掌握JVM调优的实践方面的技能。2.【MySql优化】MySql这一栏,你去b站或者找个博客看看MySql优化,学一下,如果你本身比较熟悉MySql语句的话,那基本半天时间凭你的学习能力MySql语句优化方面的技能你也能掌握个差不多。以上1,2两点主要是因为我看你专业技能大部分都说的是偏理论,没有写应用。再就是最后,你结合你的项目,想一想你的项目中哪些sql语句是可以用MySql优化的,到时候你面试的时候也好结合着说一下。
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客企业服务