天天看點

23 合并k個升序連結清單23 合并k個升序連結清單

23 合并k個升序連結清單

23 合并k個升序連結清單23 合并k個升序連結清單
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;
    }
}
           
23 合并k個升序連結清單23 合并k個升序連結清單

時間複雜度 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 (i−1)×n。第 i i i次合并的代價是 O ( ( i − 2 ) n + n ) O((i-2)n+n) O((i−2)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;

    }
}
           
23 合并k個升序連結清單23 合并k個升序連結清單

同上。

分治合并

/**
 * 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;

    }
}
           
23 合并k個升序連結清單23 合并k個升序連結清單

時間複雜度 O ( k log ⁡ k ∗ n ) O(k\log k *n) O(klogk∗n)。

空間複雜度 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;
    }
}
           
23 合并k個升序連結清單23 合并k個升序連結清單

時間複雜度 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個。