题目链接
题目描述
题解
有多种方法,这个题我使用最小堆的方法。
首先了解一下最小堆的概念:最小堆 构建、插入、删除的过程图解
解题步骤
- 首先以各链表的头指针为结点构建一棵完全二叉树。
- 按最小堆的形式整理二叉树。
- 取二叉树的根结点,连在结果链表后。
- 用根结点所在链表的下一个结点作为根结点,并重新更新为最小堆。如果没有下一个结点了,则填入一个正无穷结点。
- 重复第3步,直到根结点为正无穷结点。
代码
2020.9.5更新:使用vector维护最小堆,节省了不少时间开销和内存开销。
/*
* @lc app=leetcode.cn id=23 lang=cpp
*
* [23] 合并K个排序链表
*
* 思路:最小堆,先构造一棵结点数为链表数的最小堆(完全二叉树)。
* 依次取二叉树根结点插入结果链表,最小堆的根结点换成该结点的下一个元素,如果是NULL则换成正无穷。
*
*/
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
// 代码一:使用完全二叉树来构建,有额外的开销
/* class Solution { */
/* public: */
/* struct Node // 二叉树结点 */
/* { */
/* ListNode *node; */
/* Node *left=nullptr, *right=nullptr; */
/* }; */
/* const int MAX_NUM = 9999999; */
/* // 构建完全二叉树 */
/* void build_tree(Node *&tree_root, const vector<ListNode*> &lists) */
/* { */
/* int pos = 0; */
/* tree_root = new Node; */
/* tree_root->node = lists[pos++]; */
/* queue<Node*> Q; */
/* Q.push(tree_root); */
/* while(pos < lists.size()) */
/* { */
/* Node *node = Q.front(); */
/* Q.pop(); */
/* node->left = new Node; */
/* node->left->node = lists[pos++]; */
/* Q.push(node->left); */
/* if (pos >= lists.size()) */
/* break; */
/* node->right = new Node; */
/* node->right->node = lists[pos++]; */
/* Q.push(node->right); */
/* } */
/* } */
/* // 销毁二叉树 */
/* void destroy_tree(Node *node) */
/* { */
/* if (node == nullptr) */
/* return; */
/* destroy_tree(node->left); */
/* destroy_tree(node->right); */
/* delete node; */
/* } */
/* // 堆中元素下降 */
/* void refresh_node(Node *now) */
/* { */
/* if (now->left != nullptr && now->right != nullptr) */
/* { */
/* Node *temp = now; */
/* // 如果左右孩子都有,与其中小的比较 */
/* // 右边小 */
/* if (temp->left->node->val > temp->right->node->val) */
/*