Leetcode-23: Merge k Sorted Lists

来源:互联网 发布:交通违章查询软件下载 编辑:程序博客网 时间:2024/06/05 07:38

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

将k个有序的列表归并成一个有序列表。

思路:数据结构中学过的是k=2时的特例,不过实际都是每次都将所有列表中头元素最小的那个元素加入新的列表。有两种方法:
1)朴素的比较然后归并方法,对于每个新加入的元素都要做比较k次,那么复杂度将是O(nk),这里的比较是重复的,即加入第一个元素的时候,a0, a1, …,ak1,做了k次比较,选出最小的元素,假设为ai,第二次加入的时候,所有的头节点元素变成了a0, a1, …, bi, …, ak1,除了bi之外,其他元素都是已经做过比较的了,无需再做多余的比较,所以可以利用优先队列(最小堆)来维护这k个元素之间的顺序。建堆复杂度为O(k),每次加入新元素的复杂度为O(lgk),所以总的复杂度为O(k+(nk)lgk+klgk)=O(nlgk+k)

2)由于k>2时会带来重复比较,那么可以将k转化为k=2的问题,即使用分而治之的方法,将列表两两归并,最终归并成一条列表。k=2时,归并的复杂度为O(n),两两归并的次数共lgk次,所以复杂度为O(nlgk)

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { val = x; } * } */public class Solution {    public ListNode mergeKLists(ListNode[] lists) {        if (lists == null || lists.length == 0) return null;        if (lists.length == 1) return lists[0];        Queue<ListNode> pq = new PriorityQueue<>(lists.length, new Comparator<ListNode>(){            @Override            public int compare(ListNode l1, ListNode l2) {                if (l1.val < l2.val)                    return -1;                else if (l1.val > l2.val)                    return 1;                else                    return 0;            }        });        ListNode sential = new ListNode(0);        for (ListNode list : lists){            if (list != null)                pq.add(list);        }        ListNode tail = sential;        while (!pq.isEmpty()) {            tail.next = pq.poll();            tail = tail.next;            if (tail.next != null)                pq.add(tail.next);        }        return sential.next;    }}
原创粉丝点击