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;
    }
}
全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务