• [Leetcode]Merge Two Sorted Lists&Merge k Sorted Lists随记


    No.21, Merge Two Sorted Lists

    No.23, Merge k Sorted Lists

    第一个题是合并两个已经排序的链表,第二个题是合并k个已经排序的链表。

    第一个题是第二个题的基础,代码只贴第二题的,其中包含了第一题的方法。

    第一个题比较简单,每次取链表中未合并的部分中两个最小值比较即可,将小的放入结果链表。如果其中一个链表已经合并完成(即剩余的为空),则把另一个链表剩余的部分直接放在结果链表的最后。最坏情况下要比较m+n-1次(两个链表的长度为m,n)。

    第二题,有两种思路,一种是两两合并,一种是K个链表一起比较。

    第一种思路,也有不同的实现方案,一种是从第一个开始,顺序向下合并;另一种是按照二分的方法合并,例如一共有4个链表,lists[0]和lists[2]合并,lists[1]和lists[3]合并,再将这两个合并的结果进行合并,得到最终的结果。这两种方案复杂度是不一样的,假设所有链表一共有n个数字。第一种方法要合并k-1次,最坏情况每次合并都要比较n-k次(第一个链表长度特别长,其他链表不为空且数字比第一个链表的都要大),那么复杂度为O(nk)。第二个方法,一共要比较logk轮,n个数字在每一轮中都会参与合并1次,这里可以想象为一个二叉树,每一层都包含了n个数字一次,高度为logk,那么这里复杂度为O(nlogk)。第一种方法提交会超时,第二种AC。

    public class Solution {
             public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
                ListNode result;
                if(l1==null)
                    return l2;
                if(l2==null)
                    return l1;
                if(l1.val<=l2.val){
                    result=new ListNode(l1.val);
                    l1=l1.next;
                }
                else{
                    result=new ListNode(l2.val);
                    l2=l2.next;
                }
                ListNode p=result;
                while(l1!=null||l2!=null){
                    if(l1==null||l2!=null&&l1.val>l2.val){
                        p.next=new ListNode(l2.val);
                        l2=l2.next;
                    }
                    else if(l2==null||l1!=null&&l1.val<=l2.val){
                        p.next=new ListNode(l1.val);
                        l1=l1.next;
                    }
                    p=p.next;
                }      
                return result;
            }
        public ListNode mergeKLists(ListNode[] lists) {
            int len=lists.length;
            if(len==0)
                return null;
            while(len>1){
                int point=(len+1)/2;
                for(int i=0;i<len/2;i++){
                    lists[i]=mergeTwoLists(lists[i],lists[i+point]);
                }
                len=point;
            }
            return lists[0];
        }
    }

    那么除了两两合并,还可以k个链表一起比较。这里需要使用最小堆或者优先级队列,原理差不多,以堆为例。首先这类带有优先级的数据结构,在插入一个新的值时,重新排序的复杂度为log(n),n为节点数。我们每次都把k个链表中未合并部分的最小值组成最小堆,堆的节点数为k,堆的第一层就是最小值,即需要拿去合并的值,该值拿走后需要再用同一个链表的下一值补充。这样一共需要进行n次(n还是全部链表的数字数量),因此复杂度还是O(nlogk)。

  • 相关阅读:
    关于host,nslookup,dig 的安装
    本机网络连接虚拟机
    centos7 安装显卡驱动方法
    #2002 无法登录 MySQL 服务器
    DWM1000 定位操作流程--[蓝点无限]
    DWM1000 三基站一标签定位HEX
    DWM1000 巧用Status 快速Debug
    DWM1000 多个基站定位讨论 --[蓝点无限]
    DWM1000 收发RXLED TXLED控制代码修改
    DWM1000 多个标签定位讨论 --[蓝点无限]
  • 原文地址:https://www.cnblogs.com/lilylee/p/5235528.html
Copyright © 2020-2023  润新知