【C++算法】54.链表_合并 K 个升序链表

文章目录

    • 题目链接:
    • 题目描述:
    • 解法
    • C++ 算法代码:


题目链接:

23. 合并 K 个升序链表


题目描述:

4e3bdacde5401dc116a26c2bca8e42fa


解法

解法一:暴力解法

每个链表的平均长度为n,有k个链表,时间复杂度O(nk^2)

合并两个有序链表

先把其中的两个链表有序合并,然后把合并后的链表和后面一个链表有序合并,每次合并两个直到结束。

解法二:利用优先级队列做优化O(n*k*logk)

先给n个链表设置n个指针,然后把每个链表的第一个指针放入小根堆里面,取走堆顶元素放入newhead节点,哪一个链表的指针取走了就让那个链表指针的后一个位置放进小根堆,直到所有链表指针都指向NULL

633f4dcf38470d0f105f421514f8a803

解法三:归并排序,递归O(n*k*logk)

536ee24d1e22a89395105c6e06d2f93c


C++ 算法代码:

解法二(利用堆)

/*** 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 
{// 定义比较器结构体,用于小根堆的节点比较struct cmp{// 重载函数调用运算符,定义节点比较规则// 对于小根堆,我们需要大值返回true(表示优先级低)bool operator()(const ListNode* l1, const ListNode* l2){return l1->val > l2->val; // 如果l1值大于l2,就向下调整,返回true,实现小根堆}};
public:ListNode* mergeKLists(vector<ListNode*>& lists) {// 创建一个小根堆,存储ListNode指针// 堆会根据节点的val值自动排序,最小的在堆顶// 第一个参数 ListNode*: 指定了队列中存储的元素类型,这里是链表节点的指针// 第二个参数 vector<ListNode*>: 指定了底层容器类型,这里使用vector存储ListNode指针// 第三个参数 cmp: 指定了元素比较的方式,是一个自定义的比较器结构体priority_queue<ListNode*, vector<ListNode*>, cmp> heap;// 将所有链表的头节点加入小根堆// 只有非空链表的头节点才会被加入// auto l 会依次获取数组中的每个元素,即每个链表的头指针for(auto l : lists)if(l) heap.push(l);// 创建虚拟头节点,简化链表构建过程ListNode* ret = new ListNode(0);ListNode* prev = ret; // 使用prev作为结果链表的尾指针// 不断从堆中取出最小节点,加入结果链表while(!heap.empty()){ListNode* t = heap.top(); // 取出堆顶元素(当前所有节点中值最小的)heap.pop(); // 移除堆顶元素prev->next = t; // 将最小节点添加到结果链表prev = t; // 更新尾指针// 如果当前取出的节点还有下一个节点,将其加入堆中if(t->next) heap.push(t->next);}// 获取结果链表的头节点(跳过虚拟头节点)prev = ret->next;delete ret; // 释放虚拟头节点return prev; // 返回合并后的链表头}
};

解法三(递归/分治)

/*** 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) {// 主函数入口:调用递归函数处理整个链表数组return merge(lists, 0, lists.size() - 1);}// 分治递归函数:合并区间[left, right]内的链表ListNode* merge(vector<ListNode*>& lists, int left, int right){// 边界情况:如果left大于right,说明没有链表可合并if(left > right) return nullptr;// 边界情况:如果只有一个链表,直接返回if(left == right) return lists[left];// 1. 计算中间位置,将链表数组分为两部分int mid = left + right >> 1; // 等价于 (left + right) / 2// 2. 递归处理左右两个区间// 左区间: [left, mid]ListNode* l1 = merge(lists, left, mid);// 右区间: [mid + 1, right]ListNode* l2 = merge(lists, mid + 1, right);// 3. 合并两个区间返回的链表return mergeTowList(l1, l2);}// 合并两个有序链表ListNode* mergeTowList(ListNode* l1, ListNode* l2){// 处理边界情况if(l1 == nullptr) return l2;if(l2 == nullptr) return l1;// 创建一个临时头节点,简化合并逻辑ListNode head;ListNode* cur1 = l1;       // 指向第一个链表的当前节点ListNode* cur2 = l2;       // 指向第二个链表的当前节点ListNode* prev = &head;    // 指向合并结果的尾节点head.next = nullptr;       // 初始化临时头节点// 合并两个链表,每次取值较小的节点while(cur1 && cur2){if(cur1->val <= cur2->val){// 第一个链表的当前节点值更小,加入结果prev = prev->next = cur1;cur1 = cur1->next;}else{// 第二个链表的当前节点值更小,加入结果prev = prev->next = cur2;cur2 = cur2->next;}}// 处理剩余节点(只需处理一个链表的剩余部分)if(cur1) prev->next = cur1;if(cur2) prev->next = cur2;// 返回合并后的链表头节点return head.next;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中的注解技术讲解

Java中的注解&#xff08;Annotation&#xff09;是一种在代码中嵌入元数据的机制&#xff0c;不直接参与业务逻辑&#xff0c;而是为编译器、开发工具以及运行时提供额外的信息和指导。下面我们将由浅入深地讲解Java注解的概念、实现原理、各种应用场景&#xff0c;并通过代码…

京东与喜茶关系破裂:切断所有合作 禁止进入办公场所

快科技4月10日消息&#xff0c;据报道&#xff0c;京东集团近日被曝出内部下发全员禁令&#xff0c;全面封杀喜茶产品进入办公区域。 据知情人士透露&#xff0c;京东人力行政部门发布的通知明确规定&#xff1a;全国各职场禁止与喜茶品牌开展任何形式的合作&#xff1b;员工不…

+++++背到厌倦。持续更新

Spring IoC 的工作流程: 读取 BeanDefinition: Spring 容器启动时&#xff0c;会读取 Bean 的配置信息 (例如 XML 配置文件、注解或 Java 代码)&#xff0c;并将这些配置信息转换为 BeanDefinition 对象。创建 Bean 实例: 根据 BeanDefinition 中的信息&#xff0c;Spring 容器…

如何在Git历史中抹掉中文信息并翻译成英文

如何在Git历史中抹掉中文信息并翻译成英文 在软件开发和版本控制领域&#xff0c;维护一个清晰、一致的代码历史记录是至关重要的。然而&#xff0c;有时我们可能会遇到需要修改历史提交的情况&#xff0c;比如删除敏感信息或修正错误。本文将详细探讨如何在Git历史中抹掉中文…

21 天 Python 计划:MySQL中DML与权限管理

文章目录 前言一、介绍二、MySQL数据操作&#xff1a;DML2.1 插入数据&#xff08;INSERT&#xff09;2.1.1 插入完整数据&#xff08;顺序插入&#xff09;2.1.2 指定字段插入数据2.1.3 插入多条记录2.1.4 插入查询结果 2.2 更新数据&#xff08;UPDATE&#xff09;2.3 删除数…

微信小程序 -- 原生封装table

文章目录 table.wxmltable.wxss注意 table.js注意 结果数据结构 最近菜鸟做微信小程序的一个查询功能&#xff0c;需要展示excel里面的数据&#xff0c;但是菜鸟找了一圈&#xff0c;也没发现什么组件库有table&#xff0c;毕竟手机端好像确实不太适合做table&#xff01; 菜鸟…

LangChain-输出解析器 (Output Parsers)

输出解析器是LangChain的重要组件&#xff0c;用于将语言模型的原始文本输出转换为结构化数据。本文档详细介绍了输出解析器的类型、功能和最佳实践。 概述 语言模型通常输出自然语言文本&#xff0c;但在应用开发中&#xff0c;我们经常需要将这些文本转换为结构化的数据格式…

【安全】加密算法原理与实战

为了理解SSL/TLS原理&#xff0c;大家需要掌握一些加密算法的基础知识。当然&#xff0c;这不是为了让大家成为密码学专家&#xff0c;所以只需对基础的加密算法有一些了解即可。基础的加密算法主要有哈希&#xff08;Hash&#xff0c;或称为散列&#xff09;​、对称加密(Symm…

MySQL 优化教程:让你的数据库飞起来

文章目录 前言一、数据库设计优化1. 合理设计表结构2. 范式化与反范式化3. 合理使用索引 二、查询优化1. 避免使用 SELECT *2. 优化 WHERE 子句3. 优化 JOIN 操作 三、服务器配置优化1. 调整内存分配2. 调整并发参数3. 优化磁盘 I/O 四、监控与分析1. 使用 EXPLAIN 分析查询语句…

LangChain4j(1):初步认识Java 集成 LLM 的技术架构

LangChain 作为构建具备 LLM 能力应用的框架&#xff0c;虽在 Python 领域大放异彩&#xff0c;但 Java 开发者却只能望洋兴叹。LangChain4j 正是为解决这一困境而诞生&#xff0c;它旨在借助 LLM 的强大效能&#xff0c;增强 Java 应用&#xff0c;简化 LLM 功能在Java应用中的…

Linux服务器安装百度飞桨3.0(pip docker)

Linux安装部署百度飞桨3.0 1.官方文档指引2.确认服务器型号2.1 确认Python版本2.2 确认pip是否安装2.3 确认计算平台 3.本机安装&#xff08;基于通过 pip 安装&#xff09;3.1 下载安装 PaddlePaddle3.2 安装PaddleX3.2.1 安装PaddleX3.2.2 命令行规范3.2.3 运行示例3.2.4 查看…

Spring Boot 自动加载流程详解

前言 Spring Boot 是一个基于约定优于配置理念的框架&#xff0c;它通过自动加载机制大大简化了开发者的配置工作。本文将深入探讨 Spring Boot 的自动加载流程&#xff0c;并结合源码和 Mermaid 图表进行详细解析。 一、Spring Boot 自动加载的核心机制 Spring Boot 的自动加…

2025年危化品安全管理人员备考指南|智能题库+核心考点解析

作为危化品生产单位安全管理人员&#xff08;主要负责人&#xff09;&#xff0c;考试内容主要涵盖三大模块&#xff1a; 法律法规体系 《安全生产法》修订要点&#xff08;2023版&#xff09; 危险化学品重大危险源辨识标准&#xff08;GB 18218&#xff09; 最新《化工过…

如何优雅使用 ReentrantLock 进行加解锁:避免常见坑点,提高代码可维护性

引言&#xff1a;锁的基本概念和问题 在多线程编程中&#xff0c;为了确保多个线程在访问共享资源时不会发生冲突&#xff0c;我们通常需要使用 锁 来同步对资源的访问。Java 提供了不同的锁机制&#xff0c;其中 ReentrantLock 是一种最常用且功能强大的锁&#xff0c;它属于…

Redhat红帽 RHCE8.0认证体系课程

课程大小&#xff1a;7.7G 课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/90546064 更多资源下载&#xff1a;关注我 红帽企业 Linux 系统的管理技能已经成为现代数据中心的核心竞争力。 Linux 在支持混合云、跨物理服务器、虚机、私有云和公共云计…

Shell脚本编程

目录 1. Shell脚本概述 什么是Shell&#xff1f; Shell的作用 常见的Shell类型 2. 环境搭建与安装 Linux系统 macOS系统 Windows系统 3.安装并配置Zsh&#xff08;macOS/Linux&#xff09; 4. Shell基础语法 变量与数据类型 输入交互 5. Shell脚本进阶 进程管理 …

学生管理系统(Python)

运行结果&#xff1a; 源代码&#xff1a; """ 项目&#xff1a;类似于学生管理系统---增删改查 """ #封装一个学生类 import random class Student: def __init__(self,stuid,name,score): self.stuid stuid self.name name self.score …

电商素材革命:影刀RPA魔法指令3.0驱动批量去水印,实现秒级素材净化

本文 去除水印实操视频展示电商图片水印处理的困境​影刀 RPA 魔法指令 3.0 强势登场​利用魔法指令3.0两步实现去除水印操作关于影刀RPA 去除水印实操视频展示 我们这里选择了4张小红书里面比较帅气的图片&#xff0c;但凡用过小红书的都知道&#xff0c;小红书右下角是会有小…

Seq2Seq - GRU补充讲解

nn.GRU 是 PyTorch 中实现门控循环单元&#xff08;Gated Recurrent Unit, GRU&#xff09;的模块。GRU 是一种循环神经网络&#xff08;RNN&#xff09;的变体&#xff0c;用于处理序列数据&#xff0c;能够更好地捕捉长距离依赖关系。 ⭐重点掌握输入输出部分输入张量&#…

设计模式-观察者模式和发布订阅模式区别

文章目录 其他不错的文章 二者有类似的地方&#xff0c;也有区别。 引用的文章说的已经比较清楚了&#xff0c;这里只列出对比图。 对比点观察者模式发布订阅模式中间人角色无事件中心&#xff0c;观察者直接订阅目标有事件中心&#xff0c;发布者与订阅者通过事件中心通信关系…