携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
23. 合并K个升序链表
23. 合并K个升序链表
这是一道困难的链表题,但是也算是一道很常见,也需要学会的hard题,他算是leetcode主站21题, 21. 合并两个有序链表。和剑指offer25题, 剑指 Offer 25. 合并两个排序的链表的一个变种题目把。
做链表题目必须要先做过这两个题,才算是对链表有了基本的了解。
现在介绍这个题。
题目
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。。
示例 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 = []
输出: []
示例 3
输入: lists = [[]]
输出: []
提示:
- k == lists.length
- 0 <= k <= 10^4
- 0 <= lists[i].length <= 500
- -10^4 <= lists[i][j] <= 10^4
- lists[i] 按 升序 排列
- lists[i].length 的总和不超过 10^4
2.解法
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> queue = new PriorityQueue<>((o1,o2) -> o1.val - o2.val);
for(int i = 0; i < lists.length; i++) {
if(lists[i]!=null)
queue.offer(lists[i]);
}
ListNode res = new ListNode(0);
ListNode cur = res;
while(queue.size()>0) {
ListNode node = queue.poll();
cur.next = node;
node = node.next;
if(node!=null)
{queue.offer(node);}
cur = cur.next;
}
cur.next = queue.poll();
return res.next;
}
}
提交排名
解析
这个题起初拿到手,思考很久不知道怎么做,每次遍历各个头节点找到最小的那一个然后添加到返回ListNode的列表中吗?不仅实现复杂,而且复杂度也高。每次都要遍历,又有这么多的节点数,那时间复杂度有O(n*m)
所以想到可以运用java自带的集合类型PriorityQueue(),让优先级队列按照每个节点的val进行降序排列,每次拿出最后一个最小的节点即可。
每次拿出最小的节点Node,将Node加入返回值的链表中,然后将Node.next重新添加进PriorityQueue,直到Node.next为空的时候,就不再添加,这样当PriorityQueue中没有元素的时候,就已经排序成功了。
3.结束
这个题没做过还是难以想到的,如果做过之后,以后遇到也就不怕了,gogogo,刷题刷题,每天一道,三年1000道!!!!