23. 合并K个排序链表

知乎ID: 码蹄疾 
码蹄疾,毕业于哈尔滨工业大学。 
小米广告第三代广告引擎的设计者、开发者; 
负责小米应用商店、日历、开屏广告业务线研发;
主导小米广告引擎多个模块重构; 
关注推荐、搜索、广告领域相关知识;

题目

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
 1->4->5,
 1->3->4,
 2->6
]
输出: 1->1->2->3->4->4->5->6

分析

前面已经做过两个有序链表的合并,只要采用二分,分而治之,两两合并即可。时间复杂度方面,合并两个链表的长度的时间复杂度是o(min(m, n)),其中m,n分别是链表的长度。二合并的长度是o(logk)的时间复杂度。所以整体的时间复杂度为o(klogn)

Code

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        ListNode merged = null;
        ListNode head = null;
        while (l1 != null && l2 != null) {
            if (head == null) {
                if (l1.val < l2.val) {
                    merged = l1;
                    l1 = l1.next;
                } else {
                    merged = l2;
                    l2 = l2.next;
                }
                head = merged;
                continue;
            }

            if (l1.val < l2.val) {
                merged.next = l1;
                l1 = l1.next;
            } else {
                merged.next = l2;
                l2 = l2.next;
            }
            merged = merged.next;
        }

        while (l1 != null) {
            merged.next = l1;
            l1 = l1.next;
            merged = merged.next;
        }

        while (l2 != null) {
            merged.next = l2;
            l2 = l2.next;
            merged = merged.next;
        }
        return head;
    }

    public ListNode mergeHelper(ListNode[] lists, int low, int high) {
        if (low < high) {
            int mid = (low + high) / 2;
            ListNode leftList = mergeHelper(lists, low, mid);
            ListNode rightList = mergeHelper(lists, mid + 1, high);
            return mergeTwoLists(leftList, rightList);
        }
        return lists[low];
    }

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

拓展

合并两个有序链表,之前采用的是非递归的解法。感觉代码有点长,可以采用递归的解法,缩短代码量。合并的时候选最小的元素,链表头指针后移动,递归合并即可。

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null && l2 == null) {
            return null;
        }

        if (l1 == null) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        ListNode merged;
        if (l1.val > l2.val) {
            merged = l2;
            l2 = l2.next;
            merged.next = mergeTwoLists(l1, l2);
        } else {
            merged = l1;
            l1 = l1.next;
            merged.next = mergeTwoLists(l1, l2);
        }
        return merged;
    }
}

相关题目

21. 合并两个有序链表

原文地址:https://www.cnblogs.com/acceml/p/9313210.html

时间: 2024-08-29 05:26:17

23. 合并K个排序链表的相关文章

[leetcode] 23. 合并K个排序链表

23. 合并K个排序链表 这个题算是考察代码功底吧,基本功,对变量与引用的理解. 不多说了,思路跟第21题基本一致,只不过从两个换成了多个 class Solution { public ListNode mergeKLists(ListNode[] lists) { List<ListNode> listNodes = new ArrayList<>(Arrays.asList(lists)); ListNode ans = new ListNode(Integer.MAX_VA

LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)

23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k Sorted Lists困难 示例: 输入: [ ??1->4->5, ??1->3->4, ??2->6] 输出: 1->1->2->3->4->4->5->6 Java 实现 public class ListNode { int va

[LeetCode]23. 合并K个排序链表(优先队列;分治待做)

题目 合并?k?个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ ? 1->4->5, ? 1->3->4, ? 2->6] 输出: 1->1->2->3->4->4->5->6 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-k-sorted-lists 著作权归领扣网络所有.商业转载请联系官方授权,非商业转载请注明出处. 题解 方法

Java实现 亚博体育LeetCode 23 合并K个排序链表

合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入:[1->4->5,1->3->4,2->6]输出: 1->1->2->3->4->4->5->6 PS:直接用PriorityQueue自动排序,改写一下compare方法. /** Definition for singly-linked list. public class ListNode { int val; ListNod

23. 合并K个排序链表-LeetCode

心得:仿照归并排序,两两合并,注意更新的判断条件,注意事项看代码!!! 注意判断条件. ** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { if(lists=

23. 合并K个排序链表 分治

这种k个相同的子问题,可以两两分治,总的运算次数为logk 关键部分 int dis=1; int len=lists.size(); while(dis<=len) { for(int i=0;i<len-dis;i=i+dis*2){ lists[i]=solve(lists[i],lists[i+dis]); } dis*=2; } return lists[0]; (每次运算后剩下的子问题个数为 x/2 向上取整,这样每次/2,最后问题一定会解决) 注意判断空数组 /** * Defi

LeetCode 第23题 合并K个排序链表

/* 23. 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入:[ 1->4->5, 1->3->4, 2->6]输出: 1->1->2->3->4->4->5->6 */ /** * Definition for singly-linked list. public class ListNode { int val; ListNode next; ListNode(int * x

合并k个排序链表

题目 合并k个排序链表,并且返回合并后的排序链表.尝试分析和描述其复杂度. 样例 给出3个排序链表[2->4->null,null,-1->null],返回 -1->2->4->null 解题 两两合并 合并ab得到c 合并cd得到e /** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { * this.val =

leetcode(14)-合并k个排序链表

合并?k?个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: #输入: [ ? 1->4->5, ? 1->3->4, ? 2->6 ] #输出: 1->1->2->3->4->4->5->6 链接:https://leetcode-cn.com/problems/merge-k-sorted-lists 自己的思路 在k个链表中找到一个比较节点,然后把k个链表分成两部分,一部分都比比较节点小,一部分都比比较节点大,