打卡算法23合并K个升序链表 算法解析
Posted 恬静的小魔龙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打卡算法23合并K个升序链表 算法解析相关的知识,希望对你有一定的参考价值。
推荐阅读
大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。
一、题目
1、算法题目
“将链表数组合并到一个升序链表中。”
题目链接:
来源:力扣(LeetCode)
链接:23. 合并K个升序链表 - 力扣(LeetCode) (leetcode-cn.com)
2、题目描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入: lists = [[]]
输出: []
二、解题
1、思路分析
这个题可以采用分治和递归的思路进行解决。
首先是分治,将k个链表分成k/2个链表组,两两合并,直到合并成一个链表。
然后用递归实现分治算法。
2、代码实现
代码参考:
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode MergeKLists(ListNode[] lists) {
if(lists == null || lists.Length == 0) {
return null;
}
return MergeKLists(lists, 0, lists.Length-1);
}
private ListNode MergeKLists(ListNode[] lists, int left, int right) {
if(left == right) {
return lists[left];
}
int mid = left + (right-left)/2;
ListNode l1 = MergeKLists(lists, left, mid);
ListNode l2 = MergeKLists(lists, mid+1, right);
return MergeTwoLists(l1, l2);
}
private ListNode MergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null) {
return l2;
}
if(l2 == null) {
return l1;
}
ListNode dummy = new ListNode();
ListNode p1 = l1, p2 = l2, cur = dummy;
while(p1 != null && p2 != null) {
if(p1.val < p2.val) {
cur.next = p1;
cur = cur.next;
p1 = p1.next;
} else {
cur.next = p2;
cur = cur.next;
p2 = p2.next;
}
}
cur.next = p1 == null ? p2 : p1;
return dummy.next;
}
}
3、时间复杂度
时间复杂度 : O(n∗k∗logk)
其中链表数组长度为 k,链表的平均长度为 n。函数 MergeKLists 的时间复杂度为 O(k logk)(分治),函数 MergeTwoLists 的时间复杂度是 O(n),因此总的时间复杂度为 O(n∗k∗logk)。
空间复杂度: O(logk)
递归会使用到 O(logk) 空间代价的栈空间。
三、总结
结束条件:left == right
,即只剩下一个链表,无须合并,直接返回。
以上是关于打卡算法23合并K个升序链表 算法解析的主要内容,如果未能解决你的问题,请参考以下文章
算法leetcode|23. 合并K个升序链表(rust重拳出击)
算法leetcode|23. 合并K个升序链表(rust重拳出击)