[Leet Code] Merge k Sorted Lists

来源:互联网 发布:男士双肩包推荐知乎 编辑:程序博客网 时间:2024/05/16 10:27

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

https://oj.leetcode.com/problems/merge-k-sorted-lists/

思路1(naive):1跟2合并,然后跟3合并,然后跟4合并,一直到k个合并完。

    复杂度:1,2合并访问2n个节点,12与3合并访问3n个节点,...,123~k-1与k合并访问kn个节点,总共遍历节点数目n(3+4+5+...+k),O(nk^2)。


思路2:mergeSort的思想,K个链表先划分为合并两个k/2的链表,每个k/2的链表在划分为k/4的链表,一直到只剩一个或者两个链表。

    复杂度:T(k)=2T(k/2)+O(nk),根据主定理(算法导论上有讲),复杂度为O(nklogk)。


思路3:维护一个大小为k的堆。每次取堆顶元素放到结果中,并把该元素的后继(如果有)放入堆中。

    复杂度:每个元素读取一次nk,堆操作logk,所以复杂度为O(nklogk)。

 

思路2代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if (lists == null)
            return null;
        return merge(lists,0, lists.size() - 1);
 
    }
 
    private ListNode merge(ArrayList<ListNode> lists, int start,int end) {
        if (start == end)
            return lists.get(start);
        int mid = (start + end) / 2;
        ListNode one = merge(lists, start, mid);
        ListNode two = merge(lists, mid + 1, end);
        return mergeTwoLists(one, two);
    }
 
    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null)
            return l2;
        if (l2 == null)
            return l1;
        ListNode p1 = l1;
        ListNode p2 = l2;
 
        ListNode head = new ListNode(-1);
        head.next = p1.val <= p2.val ? p1 : p2;
        ListNode tail = head;
 
        while (p1 != null && p2 != null) {
            if (p1.val <= p2.val) {
                tail.next = p1;
                ListNode oldP1 = p1;
                p1 = p1.next;
                oldP1.next = null;
                tail = oldP1;
            }else {
                tail.next = p2;
                ListNode oldP2 = p2;
                p2 = p2.next;
                oldP2.next = null;
                tail = oldP2;
            }
 
        }
        if (p1 != null)
            tail.next = p1;
        if (p2 != null)
            tail.next = p2;
 
        return head.next;
 
    }

 

 

 

思路3代码(加测试代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Random;
 
public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if (lists == null)
            return null;
        PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>(20,new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val - o2.val;
            }
        });
        ListNode head = new ListNode(-1);
        ListNode cur = head;
        for (int i = 0; i < lists.size(); i++) {
            if (lists.get(i) != null)
                pq.add(lists.get(i));
        }
 
        while (!pq.isEmpty()) {
            ListNode out = pq.remove();
            cur.next = out;
            cur = cur.next;
            if (out.next != null)
                pq.add(out.next);
        }
 
        return head.next;
    }
 
    public static void main(String[] args) {
        ArrayList<ListNode> lists = new ArrayList<ListNode>();
        int k = 3;
        for (int i = 0; i < k; i++) {
            ListNode list = makeList(getRandomArray());
            lists.add(list);
            printList(list);
        }
        printList(new Solution().mergeKLists(lists));
 
    }
 
    private static int[] getRandomArray() {
        Random rand = new Random();
        int size = rand.nextInt(10);
        int[] res = new int[size];
        if (size == 0)
            return res;
        res[size - 1] = 100;
        for (int i = size - 2; i >= 0; i--) {
            res[i] = rand.nextInt(res[i + 1] + 1);
        }
        return res;
    }
 
    private static ListNode makeList(int[] a) {
        ListNode head = new ListNode(-1);
        ListNode p = head;
        for (int i = 0; i < a.length; i++) {
            p.next = new ListNode(a[i]);
            p = p.next;
        }
        return head.next;
 
    }
 
    private static void printList(ListNode head) {
        while (head != null) {
            System.out.print(head.val);
            if (head.next != null)
                System.out.print("->");
            head = head.next;
        }
        System.out.println();
 
    }
}
 
class ListNode {
    int val;
    ListNode next;
 
    ListNode(int x) {
        val = x;
        next = null;
    }
}

0 0
原创粉丝点击