BM5 题解 | #合并k个已排序的链表#
合并k个已排序的链表
https://www.nowcoder.com/practice/65cfde9e5b9b4cf2b6bafa5f3ef33fa6
感受进步:
well done~~!! 这道题是我自己想出来怎么实现了,中途小根堆因为放置了所有列表元素导致内存异常了,之后,看了讲解视频,调整了小根堆的元素进出,只放入k个元素,同时,再获取当前链表的下个节点,放入小根堆比较,这样减少了很多比较的工作和内存大小的占用等。
解题思路:
1、使用一个最小根堆,用for循环放入链表列表的头节点
2、定义新链表节点newHead 和 curr 赋值移动节点
3、遍历小根堆,取出最小节点存入curr,同时拿出链表的下个节点的放入小根堆比较
4、遍历完后,就获取到了新的节点返回就可以了
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
*
* @param lists ListNode类ArrayList
* @return ListNode类
*/
public ListNode mergeKLists (ArrayList<ListNode> lists) {
if (lists == null || lists.size() == 0) {
return null;
}
// 创建一个小根堆,用于去除队列中的最小值
Comparator<ListNode> cmp = new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
};
PriorityQueue<ListNode> q = new PriorityQueue<ListNode>(cmp);
// 遍历链表列表,取出列表首元素
// 为什么不是取出所有元素?因为节省内存,如果元素很对小根堆会内存溢出
for (int i = 0; i < lists.size(); i++) {
ListNode temp = lists.get(i);
if(temp!=null) {
q.offer(temp);
}
}
// 创建新表头
ListNode newHead = new ListNode(-1);
// 遍历所有新元素,同时取出列表下个元素,进行比较
ListNode curr = newHead;
while(!q.isEmpty()) {
ListNode temp = q.poll();
if(temp.next!=null){
q.offer(temp.next);
}
curr.next = temp;
curr = curr.next;
}
return newHead.next;
}
}