博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
23. 合并K个排序链表
阅读量:6886 次
发布时间:2019-06-27

本文共 2849 字,大约阅读时间需要 9 分钟。

知乎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;    }}

相关题目

 

转载于:https://www.cnblogs.com/acceml/p/9313210.html

你可能感兴趣的文章
0312-css样式(选择器、文本text、字体fonts、背景background)
查看>>
【BZOJ】4358: permu 莫队算法
查看>>
【AtCoder】ARC092 D - Two Sequences
查看>>
Android系统架构与系统源码目录
查看>>
Hash链表
查看>>
我总结的iOS开发中的几个小坑
查看>>
PS2 连接SMB(网线连电脑)和连接USB小记
查看>>
通过Web Deploy方式部署WCF
查看>>
使用xfire工具搭建webservice
查看>>
字符串与数字拼接转换
查看>>
FFMPEG 音频转换命令
查看>>
TestCase--搜索&查询模块
查看>>
Laravle Introduction
查看>>
js便签笔记(13)——jsonp其实很简单【ajax跨域请求】
查看>>
JMeter学习(一)工具简单介绍
查看>>
leetcode/2017-1-1
查看>>
正则表达式 分组
查看>>
python 文件中字符串过滤,并将结果输出到另一个文件中(源码)
查看>>
E:in-range伪类选择器与E:out-of-range伪类选择器
查看>>
签名--数字证书原理
查看>>