【LeetCode】Merge k Sorted Lists 解题报告

【题目】

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

合并几个有序链表为一个,分析算法复杂度。

【分治】

直观的想法是两两合并,有两种方法:1)list1和list2合并为newlist2,newlist2再和list3合并为newlist3,newlist3再和list4合并为newlist4……依次类推;2)list1和list2合并为list12,list3和list4合并为list34……然后list12再和list34合并……直到合并为一个list。

那么这两种方法有什么区别?

参考博客 http://www.cnblogs.com/TenosDoIt/p/3673188.html 得知,这两种方法时间复杂度并不一样,关键在于链表是有长度的。

方法1:1、2合并,遍历2n个节点;12结果和3合并,遍历3n个节点;123结果和4合并,遍历4n个节点;…… 123..k-1结果和k合并,遍历kn个节点;总共遍历的节点数目为n(2+3+…+k) = n*(k^2+k-2)/2, 因此时间复杂度是O(n*(k^2+k-2)/2) = O(nk^2)。

方法2:就是分治,算法复杂度为T(k) = 2T(k/2) + O(nk),很简单可以推导得到算法复杂度为O(nklogk)。

其实个人觉得,两种方法的区别就在于方法2每次合并的两个链表长度都比较接近,不管原始链表长度是否比较均等,最起码比方法1每次合并的两个链表长度之差小。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode mergeKLists(List<ListNode> lists) {
        if (lists == null || lists.size() < 1) return null;
        return mergeLists(lists, 0, lists.size() - 1);
    }

    public ListNode mergeLists(List<ListNode> lists, int from, int to) {
        if (from < to) {
            int mid = (from + to) / 2;
            return merge2Lists(mergeLists(lists, from, mid), mergeLists(lists, mid + 1, to));
        }
        return lists.get(from);
    }

    public ListNode merge2Lists(ListNode head1, ListNode head2) {
        if (head1 == null) return head2;
        if (head2 == null) return head1;

        ListNode newHead = head1;
        ListNode node1 = head1, node2 = head2;
        if (head1.val > head2.val) {
            node1 = head2;
            node2 = head1;
            newHead = head2;
        }

        while (node1.next != null && node2 != null) {
            if (node2.val < node1.next.val) {
                ListNode tmp = node2.next;
                node2.next = node1.next;
                node1.next = node2;
                node1 = node1.next;
                node2 = tmp;
            } else {
                node1 = node1.next;
            }
        }

        if (node2 != null) {
            node1.next = node2;
        }

        return newHead;
    }

}

【优先队列】

维护一个优先级队列,把所有链表的头结点也就是最小的结点放入队列中,每次从队列中取出最小的元素,然后再把原链表中该元素后面的结点加入优先队列,直到队列为空。

把结点加入优先队列的时间复杂度为O(lgk),总共kn个结点,所以总的时间复杂度为O(knlgk),与分治一样。

public class Solution {
    public ListNode mergeKLists(List<ListNode> lists) {
        if (lists == null || lists.size() < 1) return null;

        Comparator<ListNode> cmp =  new Comparator<ListNode>() {
    	    public int compare(ListNode node1, ListNode node2) {
    	        return node1.val - node2.val;
    	    }
    	};
        PriorityQueue<ListNode> queue = new PriorityQueue<ListNode>(lists.size(), cmp);

        for (int i = 0; i < lists.size(); i++) {
            if (lists.get(i) != null) {
                queue.offer(lists.get(i));
            }
        }

        ListNode newHead = new ListNode(0);
        ListNode pre = newHead;
        while (!queue.isEmpty()) {
            ListNode cur = queue.poll();
            if (cur.next != null) {
                queue.offer(cur.next);
            }
            pre.next = cur;
            pre = pre.next;
        }

        return newHead.next;
    }
}

参考来源:http://blog.csdn.net/linhuanmars/article/details/19899259

时间: 2024-10-03 02:04:54

【LeetCode】Merge k Sorted Lists 解题报告的相关文章

LeetCode: Merge k Sorted Lists 解题报告

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Show Tags 参考资料: http://blog.csdn.net/linhuanmars/article/details/19899259. SOLUTION 1: 使用分治法.左右分别递归调用Merge K sorted List,然后再使用merg

LeetCode: Merge Two Sorted Lists 解题报告

Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. Show Tags SOLUTION 1: 使用dummynode记录头节点的前一个,轻松完成,2分钟就AC啦! 1 /** 2 * Definition for sin

LeetCode Merge k Sorted Lists 解决报告

https://oj.leetcode.com/problems/merge-k-sorted-lists/ 归并K已经整理阵列,和分析算法的复杂. 解决报告:无论是不考虑优化,最简单的实现是要重新走路List<ListNode>.对当中每一个链表同当前链表做一遍类似于归并排序最后一步的merge操作. 算法复杂度是O(KN) public class Solution { ListNode mergeTwoLists(ListNode list1, ListNode list2) { Lis

[leetcode]Merge k Sorted Lists @ Python

原题地址:https://oj.leetcode.com/problems/merge-k-sorted-lists/ 题意:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解题思路:归并k个已经排好序的链表.使用堆这一数据结构,首先将每条链表的头节点进入堆中,然后将最小的弹出,并将最小的节点这条链表的下一个节点入堆,依次类推,最终形成的链表就是归

LeetCode: Merge k Sorted Lists [022]

[题目] Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. [题意] 合并K个有序链表 [思路] 归并 [代码] /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), n

[leetcode]Merge k Sorted Lists @ Python [基础知识: heap]

原题地址:https://oj.leetcode.com/problems/merge-k-sorted-lists/ 题意:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解题思路: 归并k个已经排好序的链表, 使用堆这一数据结构. 堆,也叫做:priority queue 首先将每条链表的头节点进入堆中. 然后将最小的弹出,并将最小的节点这条链

LeetCode -- Merge k Sorted Lists (Divide and Conquer / PriorityQueue)

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 分支策略:每次归并两个已排好序的链表,直至只剩下一个链表. public class Solution { public ListNode mergeKLists(List<ListNode> lists) { //处理特殊情况  if (lists == null)             ret

LeetCode Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { 7 * val = x; 8 * next =

[Leetcode] Merge k sorted lists 合并k个已排序的链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:这题最容易想到的是,(假设有k个链表)链表1.2合并,然后其结果12和3合并,以此类推,最后是123--k-1和k合并.至于两链表合并的过程见merge two sorted lists的分析.复杂度的分析见JustDoIT的博客.算法复杂度:假设每个链表的平均长度是n,则1.2合并,遍历2n个