力扣HOT100之链表:23. 合并 K 个升序链表

这道题我是用最淳朴最简单的思路去做的,用一个while循环持续地将当前遍历到的最小值加入到合并链表中,while循环中使用一个for循环遍历整个指针数组,将其中的最小值和对应下标记录下来,并将其值加入到合并链表中,同时对应的那条链表的指针后移一位。这里我们需要用到一个额外的辅助变量flag,在每一次执行for循环之前需要初始化为false,默认为所有链表都已经遍历到末尾,在for循环中,如果遇到了还没遍历到末尾的链表,则flag会被更新为true,该标志位的作用就是用来标记所有链表是否遍历结束,如果遍历结束就直接跳出外层的while循环。

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* result = new ListNode();
        ListNode* temp = result;
        bool flag = lists.size() == 0 ? false : true;
        while(flag){
            int min_value = INT_MAX;
            int min_index = INT_MAX;
            flag = false;
            for(int i = 0; i < lists.size(); ++i){
                if(!lists[i]){    //若当前遍历到的链表已经遍历到末尾,则直接跳过当前链表
                    flag = false || flag;
                    continue;   
                } 
                flag = true;  //尚有链表没有遍历结束
                if(lists[i] -> val < min_value){
                    min_value = lists[i] -> val;  //更新当前节点的最小值
                    min_index = i;   //更新最小值的下标
                }
            }
            if(flag){
                temp -> next = new ListNode(min_value);
                cout << min_value << endl;
                temp = temp -> next;
                lists[min_index] = lists[min_index] -> next;
            }
        }
        return result -> next;
    }
};

但是这么做的耗时有点太长了,AC之后去看了下灵神的题解,感觉他的第一种思路特别通俗易懂,主要是借用了数据结构本身的特性,利用优先队列进行自动排序,而无需手动排序,因此我们只需要不断地将节点加入到优先队列中即可,这道题需要我们自定义一个排序规则,以对链表节点进行排序,当我们把优先队列的队头元素(队列内的最小值)取出后,我们需要判断队头元素的下一个节点是否为空,若不为空才将下一个节点加入到优先队列中。当所有链表的所有节点都被加入到优先队列中后,我们直接退出循环。

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* result = new ListNode();
        ListNode* temp = result;
        // 使用Lambda表达式定义比较规则
        auto compare = [] (const ListNode* a, const ListNode* b) {
            return a -> val > b -> val;    //较小的优先级较高
        };
        priority_queue<ListNode*, vector<ListNode*>, decltype(compare)> q;   //优先队列,存储值较小的排前面
        for(auto head : lists){
            if(head) q.push(head);  //将所有的非空链表头节点入队
        }
        while(!q.empty()){
            temp -> next = new ListNode(q.top() -> val);
            cout << q.top() -> val << endl;
            if(q.top() -> next)  //下个节点不为空才入队
                q.push(q.top() -> next);
            q.pop();
            temp = temp -> next;
        }
        return result -> next;
    }
};
相关推荐
2401_8724187810 小时前
算法入门:数据结构-堆
数据结构·算法
xwz小王子11 小时前
手术机器人登上Science Robotics:2毫米纤细手臂,从3厘米切口完成腰椎神经减压
算法·机器人
黎阳之光12 小时前
视频孪生智护供水生命线:黎阳之光赋能医疗与园区水务高质量升级
运维·物联网·算法·安全·数字孪生
Black蜡笔小新12 小时前
自动化AI算法训练服务器DLTM制造业AI质检工作站助力制造业实现AI智检
人工智能·算法·自动化
嵌入式小能手12 小时前
飞凌嵌入式ElfBoard-进程间的通信之命名管道
linux·服务器·算法
啦哈拉哈13 小时前
Leetcode题解记录-hot100(81-100)
算法·leetcode·职场和发展
csdn_aspnet13 小时前
Java 霍尔分区算法(Hoare‘s Partition Algorithm)
java·开发语言·算法
诸葛务农13 小时前
道路行驶条件下电动汽车永磁电机的有效使用寿命及永磁体的失效和回收再利用(下)
java·开发语言·算法
snow@li13 小时前
AI:理解 大数据、算法、算力、电力、生成式AI、token 之间的关系
大数据·人工智能·算法
小智老师PMP13 小时前
零基础能不能考PMP?零基础专属学习路径+全套扶持体系
学习·算法·职场和发展·软件工程·求职招聘·敏捷流程