23 合并k个升序链表

23 合并k个升序链表

在这里插入图片描述
在这里插入图片描述

顺序合并01

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        int len = lists.length;
        if(lists.length==0){
            return null;
        }
        if(lists.length==1){
            return lists[0];
        }
        ListNode res = new ListNode();
        res = lists[0];
        for(int i=1;i<len;i++){
            res = merge(res,lists[i]);
        }
        return res;

    }
    public ListNode merge(ListNode list1,ListNode list2){
        if(list1==null){
            return list2;
        }
        if(list2==null){
            return list1;
        }
        ListNode pre = new ListNode();
        ListNode cur = list1;
        ListNode p2 = list2;
        while(cur!=null && p2!=null){
            if(cur.val<p2.val){
                pre = cur;
                cur = cur.next;
            }else{
                pre.next = p2;
                p2 = p2.next;
                pre.next.next=cur;
                pre = pre.next;
            }
        }
        if (p2!=null){

            pre.next=p2;
        }
        if (list1.val<list2.val){
            return list1;
        }
        return list2;
    }
}

在这里插入图片描述
时间复杂度 O ( k 2 n ) O(k^2n) O(k2n)。假设每个链表的最长长度是 n n n。第一次合并后 r e s res res的长度为 2 n 2n 2n,第 i i i次合并后, r e s res res的长度为 ( i − 1 ) × n (i-1)\times n (i1)×n。第 i i i次合并的代价是 O ( ( i − 2 ) n + n ) O((i-2)n+n) O((i2)n+n)。总的时间代价是 O ( k 2 n ) O(k^2n) O(k2n)
空间复杂度 O ( 1 ) O(1) O(1)

顺序合并02

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        int len = lists.length;
        if(lists.length==0){
            return null;
        }
        if(lists.length==1){
            return lists[0];
        }
        ListNode res = new ListNode();
        res = lists[0];
        for(int i=1;i<len;i++){
            res = merge(res,lists[i]);
        }
        return res;

    }
    public ListNode merge(ListNode list1,ListNode list2){
        ListNode head = new ListNode();
        ListNode p = head;
        ListNode p1 = list1;
        ListNode p2 = list2;
        while(p1!=null && p2!=null){
            if(p1.val<p2.val){
                p.next = p1;
                p=p.next;
                p1 = p1.next;
            }else{
                p.next=p2;
                p=p.next;
                p2=p2.next;
            }
        }
        if (p1!=null){
            p.next=p1;
        }
        if(p2!=null){
            p.next=p2;
        }
        return head.next;

    }
}

在这里插入图片描述
同上。

分治合并

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        return mergeList(lists,0,lists.length-1);

    }
    public ListNode mergeList(ListNode[] lists,int l,int r){
        if(l==r){
            return lists[l];
        }
        if (l>r){
            return null;
        }
        int mid = (l+r)/2;
        return merge(mergeList(lists,l,mid),mergeList(lists,mid+1,r));
    }

    public ListNode merge(ListNode list1,ListNode list2){
        ListNode head = new ListNode();
        ListNode p = head;
        ListNode p1 = list1;
        ListNode p2 = list2;
        while(p1!=null && p2!=null){
            if(p1.val<p2.val){
                p.next = p1;
                p=p.next;
                p1 = p1.next;
            }else{
                p.next=p2;
                p=p.next;
                p2=p2.next;
            }
        }
        if (p1!=null){
            p.next=p1;
        }
        if(p2!=null){
            p.next=p2;
        }
        return head.next;

    }
}

在这里插入图片描述
时间复杂度 O ( k log ⁡ k ∗ n ) O(k\log k *n) O(klogkn)
空间复杂度 O ( log ⁡ k ) O(\log k) O(logk)

优先队列

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length==0){
            return null;
        }
        if(lists.length==1){
            return lists[0];
        }
        PriorityQueue<ListNode> que = new PriorityQueue<>(new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val-o2.val;
            }
        });
        ListNode head = new ListNode(0);
        ListNode p = head;
        for(int  i=0;i<lists.length;i++){
            if(lists[i]==null){
                continue;
            }
            que.add(lists[i]);
        }

        while (!que.isEmpty()){
            ListNode tmp = que.poll();
            if (tmp==null){
                continue;
            }
            p.next = tmp;
            p=p.next;
            tmp=tmp.next;
            if (tmp!=null){
                que.add(tmp);
            }

        }
        return head.next;
    }
}

在这里插入图片描述
时间复杂度 O ( k n × log ⁡ k ) O(kn \times \log k) O(kn×logk)。优先队列中的元素不超过 k k k个,那么插入和删除的时间代价为 O ( log ⁡ k ) O(\log k) O(logk),这里最多有 k n kn kn个点,对于每个点都被插入和删除一次,故总的时间代价即为 O ( k n × log ⁡ k ) O(kn \times \log k) O(kn×logk)
空间复杂度 O ( k ) O(k) O(k),优先队列中的元素不超过 k k k个。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值