[LeetCode] 23. Merge k Sorted Lists java

    /**23. Merge k Sorted Lists
     * @param lists
     * @return 合并k路有序链表
     */
    public ListNode mergeKLists(ListNode[] lists) {  
        int n = lists.length;
        if (n == 0)
            return null;
        else if (n == 1)
            return lists[0];
        for (int i=1; i<n; i++) {
            lists[0] = mergeTwoLists(lists[i], lists[i-1]);
        }
        return lists[0];
    }
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode ret = new ListNode(-1);
        ListNode retHead = ret;
        if (l1 == null && l2 == null) {
            return null;
        }else if (l1 == null) {
            return l2;
        } else if (l2 == null) {
            return l1;
        }
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                ret.next = l1;
                l1 = l1.next;
                ret = ret.next;
            } else {
                ret.next = l2;
                l2 = l2.next;
                ret = ret.next;
            }
        }
        if (l1 != null) {
            ret.next = l1;
        }
        if (l2 != null) {
            ret.next = l2;
        }
        return retHead.next;
    }

//Time limit,

    public ListNode mergeKLists(ListNode[] lists) {  
        if (lists == null || lists.length == 0)
            return null;
        return merge(lists, 0, lists.length-1);
    }
    public ListNode merge(ListNode[] lists, int low, int high) {
        if (low < high) {
            int mid = (low+high)/2;
            ListNode left = merge(lists, low, mid);
            ListNode right = merge(lists, mid+1, high);
            return mergeTwoLists(left, right);
        }
        return lists[low];
    }

归并操作,减小时间复杂度

下面这个方法使用最小堆

    public ListNode mergeKLists1(ListNode[] lists) {  
        PriorityQueue<ListNode> heap = new PriorityQueue<ListNode> (10,new Comparator<ListNode>(){  
                @Override  
                public int compare(ListNode n1, ListNode n2)  
                {  
                    return n1.val-n2.val;  
                }  
        });  
        for(int i=0;i<lists.length;i++)  
        {  
            ListNode node = lists[i];   
            if(node!=null)  
            {  
                heap.offer(node);  
            }  
        }  
        ListNode head = null;  
        ListNode pre = head;  
        while(heap.size()>0)  
        {  
            ListNode cur = heap.poll();  
            if(head == null)  
            {  
                head = cur;  
                pre = head;  
            }  
            else  
            {  
                pre.next = cur;  
            }  
            pre = cur;  
            if(cur.next!=null)  
                heap.offer(cur.next);  
        }  
        return head;  
    } 


维护一个大小为k的堆,每次取堆顶的最小元素放到结果中,然后读取该元素的下一个元素放入堆中,重新维护好。
因为每个链表是有序的,每次又是去当前k个元素中最小的,所以当所有链表都读完时结束,这个时候所有元素按从小到大放在结果链表中。
这个算法每个元素要读取一次,即是k*n次,然后每次读取元素要把新元素插入堆中要logk的复杂度,
所以总时间复杂度是O(nklogk)。空间复杂度是堆的大小,即为O(k)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值