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