[LeetCode] 23. 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.
 * 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;

        } else if (lists.length == 1) {
            return lists[0];

        } else {
            ListNode res = new ListNode(0);
            ListNode last = res;

            int mid = lists.length / 2;
            ListNode one = mergeKLists(Arrays.copyOfRange(lists, 0, mid));
            ListNode two = mergeKLists(Arrays.copyOfRange(lists, mid, lists.length));

            while (one != null && two != null) {
                if (one.val < two.val) {
                    last.next = one;
                    one = one.next;
                } else {
                    last.next = two;
                    two = two.next;
                }
                last = last.next;
            }

            last.next = one != null ? one : two;
            return res.next;
        }

    }
}

或者:

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

        int n = lists.length;
        while (n > 1) {
            int k = (n + 1) / 2;
            for (int i = 0; i < n / 2; i++) {
                lists[i] = mergeTwoLists(lists[i], lists[i + k]);
            }
            n = k;
        }
        return lists[0];
    }

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode head = new ListNode(0);
        ListNode last = head;

        while (list1 != null && list2 != null) {
            if (list1.val < list2.val) {
                last.next = list1;
                list1 = list1.next;
            } else {
                last.next = list2;
                list2 = list2.next;
            }
            last = last.next;
        }

        last.next = list1 != null ? list1 : list2;
        return head.next;
    }
}

解法2:

  采用小根堆的方法,先将k个链表的首节点加入堆中,每次会自动输出最小的节点,将该节点加入到最终结果的链表中,然后将其下一个元素(如果不为null)加入堆中,直到最终堆为空,即输出了全部元素。代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>() {
        public int compare(ListNode left, ListNode right) {
            if (left == null) {
                return 1;  // 这样操作的原因是,确保堆顶(最小节点)不会为null
            } else if (right == null) {
                return -1;  // 这样操作的原因是,确保堆顶(最小节点)不会为null
            } // 因为下面操作中确保堆中不会有null,所以这两个判断不要亦可
            return left.val - right.val;
        }
    };

    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) {
            return null;
        }

        Queue<ListNode> heap = new PriorityQueue<ListNode>(lists.length, ListNodeComparator);
        for (ListNode node : lists) {
            if (node != null) {
                heap.add(node);
            }
        }

        ListNode dummy = new ListNode(0);
        ListNode last = dummy;
        while (!heap.isEmpty()) {
            last.next = heap.poll();
            last = last.next;
            if (last.next != null) {
                heap.add(last.next);
            }
        }
        return dummy.next;
    }
}
时间: 2024-10-18 11:01:38

[LeetCode] 23. Merge k Sorted Lists ☆☆的相关文章

[LeetCode]23. Merge k Sorted Lists

23. Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 给定k个排序了的链表,合并k个链表成一个排序链表. 本程序思路: 1)首先得到K个链表的长度和存在len中 2)从K个链表中找到值最小的那个节点,把该节点添加到合并链表中 3)重复len次即可把所有节点添加到合并链表中. 注意事项: 1)K个链表中有的

[LeetCode] 23. Merge k Sorted Lists 合并k个有序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 与21. Merge Two Sorted Lists的拓展,这道题要合并k个有序链表,还是可以两两合并. 类似题目: [LeetCode] 21. Merge Two Sorted Lists 合并有序链表 原文地址:https://www.cnblogs.com/lightwindy/p/8512

leetCode 23. Merge k Sorted Lists (合并k个排序链表) 解题思路和方法

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:此题是由合并两个排序链表演化而来,刚开始,想法比较简单,像求最大公共前缀一样,逐一求解:但是最后超时,所以马上意识到出题方是为了使用归并和分治的方法,故重新写了代码. 代码一(超时未过): /** * Definition for singly-link

LeetCode #23 Merge k Sorted Lists (H)

[Problem] Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. [Analysis] 这题一上来,就会想到之前做过的Merge Two Sorted Lists.但是如果单纯地不断将新的list merge进结果,复杂度是非常高的,因为仔细想想就会发现在这个过程中结果里已经merge过的元素需要被重新排序,而这一部分无用功是可以通过使用合理的技

leetcode 23. Merge k Sorted Lists(堆||分治法)

Merge k sorted linked lists and return it as one sorted list. 题意:把k个已经排好序的链表整合到一个链表中,并且这个链表是排了序的. 题解:这是一道经典好题,值得仔细一说. 有两种方法,假设每个链表的平均长度是n,那么这两种方法的时间复杂度都是O(nklogk). 方法一: 基本思路是:把k个链表开头的值排个序,每次取最小的一个值放到答案链表中,这次取完之后更新这个值为它后面的一个值.接着这么取一直到全部取完.那么每次更新之后怎么对当

Java [leetcode 23]Merge k Sorted Lists

题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解题思路: 分而自治方法.将K个List不断地分解为前半部分和后半部分.分别进行两个List的合并.最后将合并的结果合并起来. 代码如下: /** * Definition for singly-linked list. * public class ListNode { * int va

LeetCode 23 Merge k Sorted Lists (C,C++,Java,Python)

Problem: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Solution: 采用胜者树的方法,胜者树介绍:胜者树,假如链表数组长度为n,链表元素总个数为k,那么时间复杂度为O(k*log(n)) 题目大意: 给定一个数组有序链表(数组元素可能为空),要求将这些链表合并为一个有序的链表. Java源代码(522ms): /** * Defi

[LeetCode]23. Merge k Sorted Lists合并K个排序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Example: Input: [   1->4->5,   1->3->4,   2->6 ] Output: 1->1->2->3->4->4->5->6 要合并K个排好序的链表,我用的方法是用一个优先队列每次存K个元素在队列中,根据优

23. Merge k Sorted Lists - LeetCode

Question 23.?Merge k Sorted Lists Solution 题目大意:合并链表数组(每个链表中的元素是有序的),要求合并后的链表也是有序的 思路:遍历链表数组,每次取最小节点 Java实现: public ListNode mergeKLists(ListNode[] lists) { ListNode preHead = new ListNode(0); ListNode minNode = getMinNode(lists); ListNode tmpNode =