当前位置: 首页 > news >正文

LeetCode刷题 -- 23. 合并 K 个升序链表

小根堆排序与合并 K 个有序链表的实现

1. 介绍

本技术文档详细介绍了如何使用 小根堆(Min Heap) 实现 K 个有序链表的合并

核心思想是:

  1. 使用 小根堆 维护当前最小的节点。
  2. 每次取出堆顶元素(最小值)加入合并链表,并插入新的最小节点。
  3. 直至所有链表合并完成。

2. 代码结构

本实现包括以下关键部分:

  • 交换函数 (swap):用于交换两个链表节点的指针。
  • 调整堆 (min_downmin_up):维护小根堆的性质。
  • 堆排序 (min_heap_sort):对链表数组进行初始堆化。
  • 链表比较函数 (int_compare):比较链表节点的 val 值。
  • 合并 K 个链表 (mergeKLists):主函数,使用小根堆合并链表。

3. 代码实现

3.1 交换函数

/* 交换两个指针变量的值 */
static void swap(void *a, void *b, size_t size) {struct ListNode* tmp = NULL;tmp = *((struct ListNode**)a);*((struct ListNode**)a) = *((struct ListNode**)b);*((struct ListNode**)b) = tmp;
}

3.2 小根堆调整

3.2.1 min_down - 下滤调整堆
static void min_down(void *base, size_t nmemb, size_t size, size_t root, compare_func cmp) {size_t smallest = root;size_t left = 2 * root + 1;size_t right = 2 * root + 2;char *arr = (char *)base;if (left < nmemb && cmp(arr + left * size, arr + smallest * size) < 0) {smallest = left;}if (right < nmemb && cmp(arr + right * size, arr + smallest * size) < 0) {smallest = right;}if (smallest != root) {swap(arr + root * size, arr + smallest * size, size);min_down(base, nmemb, size, smallest, cmp);}
}
3.2.2 min_up - 上滤调整堆
static void min_up(void *base, size_t size, size_t root, compare_func cmp) {size_t smallest = root;size_t parent = (root - 1) / 2;char *arr = (char *)base;if (root == 0) return;if (cmp(arr + parent * size, arr + smallest * size) > 0) {smallest = parent;}if (smallest != root) {swap(arr + root * size, arr + smallest * size, size);min_up(base, size, smallest, cmp);}
}

3.3 小根堆排序

void min_heap_sort(void *base, size_t nmemb, size_t size, compare_func cmp) {if (nmemb < 2) return;for (int i = (nmemb / 2) - 1; i >= 0; i--) {min_down(base, nmemb, size, i, cmp);}
}

3.4 比较函数

int int_compare(const void *a, const void *b) {return (*(struct ListNode **)a)->val - (*(struct ListNode **)b)->val;
}

3.5 合并 K 个有序链表

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {int leave_size = 0;struct ListNode *result = NULL;struct ListNode *tail = NULL;for (int i = 0; i < listsSize; i++) {if (lists[i] != NULL) {lists[leave_size] = lists[i];leave_size++;}}if (leave_size < 1) return NULL;if (leave_size == 1) return lists[0];min_heap_sort(lists, leave_size, sizeof(struct ListNode *), int_compare);while (leave_size > 1) {min_down(lists, leave_size, sizeof(struct ListNode *), 0, int_compare);if (result == NULL) {result = lists[0];lists[0] = lists[0]->next;tail = result;} else {tail->next = lists[0];lists[0] = lists[0]->next;tail = tail->next;tail->next = NULL;}if (lists[0] == NULL) {lists[0] = lists[leave_size - 1];leave_size--;}}if (lists != NULL && lists[0] != NULL) {tail->next = lists[0];tail = tail->next;}return result;
}

4. 复杂度分析

  1. 堆化过程: 复杂度为 O(n)
  2. 每次插入或删除节点: 复杂度为 O(log k)
  3. 总操作数: O(n log k)

其中,n 是所有链表节点总数,k 是链表个数。


5. 结论

该算法利用 小根堆 维护 K 个链表的最小值,每次取出最小值并合并,使得整体时间复杂度达到 O(n log k),远优于直接合并(O(nk))。

适用于 大规模链表合并 任务,在 合并排序优先队列 相关应用场景中有重要应用。

相关文章:

LeetCode刷题 -- 23. 合并 K 个升序链表

小根堆排序与合并 K 个有序链表的实现 1. 介绍 本技术文档详细介绍了如何使用 小根堆&#xff08;Min Heap&#xff09; 实现 K 个有序链表的合并。 核心思想是&#xff1a; 使用 小根堆 维护当前最小的节点。每次取出堆顶元素&#xff08;最小值&#xff09;加入合并链表&…...

DeepSeek在MATLAB上的部署与应用

在科技飞速发展的当下&#xff0c;人工智能与编程语言的融合不断拓展着创新边界。DeepSeek作为一款备受瞩目的大语言模型&#xff0c;其在自然语言处理领域展现出强大的能力。而MATLAB&#xff0c;作为科学计算和工程领域广泛应用的专业软件&#xff0c;拥有丰富的工具包和高效…...

mapbox基础,使用geojson加载fill-extrusion三维填充图层

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️fill-extrusion三维填充图层样式二、�…...

基于 SpringBoot 的 “电影交流平台小程序” 系统的设计与实现

大家好&#xff0c;今天要和大家聊的是一款基于 SpringBoot 的 “电影交流平台小程序” 系统的设计与实现。项目源码以及部署相关事宜请联系我&#xff0c;文末附上联系方式。 项目简介 基于 SpringBoot 的 “电影交流平台小程序” 系统设计与实现的主要使用者分为 管理员 和…...

单片机裸机编程-时机管理

对于 RTOS 实时操作系统&#xff0c;我们是通过 TASK&#xff08;任务&#xff09;进行底层操作的&#xff0c;这与裸机编程中的函数&#xff08;fun&#xff09;类似。不同的任务或函数实现不同的功能&#xff0c;在RTOS中&#xff0c;单片机有信号量、队列等不同任务之间的通…...

Flutter系列教程之(2)——Dart语言快速入门

目录 1.变量与类型 1.1 num类型 1.2 String类型 1.3 Object与Dynamic 1.4 类型判断/转换 1.5 变量和常量 2.方法/函数 3.类、接口、抽象类 3.1 类 3.2 接口 4.集合 4.1 List 4.2 Set 4.3 Map 5.总结 Dart语言的语法和Kotlin、Java有类似之处&#xff0c;这里就通…...

pyecharts介绍

文章目录 介绍安装pyecharts基本使用全局配置选项 折线图相关配置地图模块使用柱状图使用 介绍 echarts虑是个由百度开源的数据可视化&#xff0c;凭借着良好的交互性&#xff0c;精巧的图表设计&#xff0c;得到了众多开发者的认可&#xff0c;而Pyhon是门富有表达力的语言&a…...

前缀和相关题目记录(未完待续...)

1 前缀和 一维前缀和是指对于一个数组 a a a&#xff0c;我们定义一个新的数组 s s s&#xff0c;其中每个元素 s [ i ] s[i] s[i] 表示从数组开头到第 i i i 个元素的累加和&#xff1a; s [ i ] a [ 1 ] a [ 2 ] ⋯ a [ i ] ∑ j 1 i a [ j ] s[i] a[1] a[2] \…...

Https解决了Http的哪些问题

部分内容来源&#xff1a;小林coding 详细解析 Http的风险 HTTP 由于是明文传输&#xff0c;所以安全上存在以下三个风险&#xff1a; 1.窃听风险 比如通信链路上可以获取通信内容&#xff0c;用户号容易没。 2.篡改风险 比如强制植入垃圾广告&#xff0c;视觉污染&#…...

OpenCV给图像添加噪声

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 如果你已经有了一张干净的图像&#xff0c;并希望通过编程方式向其添加噪声&#xff0c;可以使用 OpenCV 来实现这一点。以下是一个简单的例子&a…...

湖北中医药大学谱度众合(武汉)生命科技有限公司研究生工作站揭牌

2025年2月11日&#xff0c;湖北中医药大学&谱度众合&#xff08;武汉&#xff09;生命科技有限公司研究生工作站揭牌仪式在武汉生物技术研究院一楼101会议室举行&#xff0c;湖北中医药大学研究生院院长刘娅教授、基础医学院院长孔明望教授、基础医学院赵敏教授、基础医学院…...

欢乐力扣:快乐数

文章目录 1、题目描述2、思路1代码 1、题目描述 快乐数。  编写一个算法来判断一个数 n 是不是快乐数。  快乐数定义为&#xff1a;对于一个正整数&#xff0c;每次不断将其转化成 每位数字的平方和。 判断是否最终和会为1&#xff0c;是1就是快乐数&#xff0c;否则不是。 …...

【聊天室后端服务器开发】功能设计-框架与微服务

服务器功能设计 微服务思想应用 微服务架构 主要组成分析 客户端 客户端通过 HTTP 协议与网关进行交互&#xff0c;进行操作如用户注册、好友申请等客户端只需要知道网关的地址&#xff0c;无需关心后端服务的具体实现 网关 作为系统的统一入口&#xff0c;网关负责接收客…...

国标28181协议在智联视频超融合平台中的接入方法

一. 国标28181介绍 国标 28181 协议全称是《安全防范视频监控联网系统信息传输、交换、控制技术要求》&#xff0c;是国内视频行业最重要的国家标准&#xff0c;目前有三个版本&#xff1a; 2011 年&#xff1a;推出 GB/T 28181-2011 版本&#xff0c;为安防行业的前端设备、平…...

让网页“浪“起来:打造会呼吸的波浪背景

每次打开那些让人眼前一亮的网页时&#xff0c;你是否有注意到那些看似随波逐流的动态背景&#xff1f;今天咱们不聊高深的技术&#xff0c;就用最朴素的CSS&#xff0c;来解锁这个让页面瞬间鲜活的秘籍。无需JavaScript&#xff0c;不用复杂框架&#xff0c;准备好一杯咖啡&am…...

linux-多进程基础(1) 程序、进程、多道程序、并发与并行、进程相关命令,fork

程序是什么 程序是包含一系列信息的文件。这些信息描述了如何在运行时创建一个进程&#xff0c;包含二进制格式标识、机器语言指令、程序入口地址、数据、符号表及重定位表、共享库信息及其他信息 二进制格式标识&#xff0c;每个程序包含了描述可执行文件的元信息(是否可读之…...

美颜相机1.0

项目开发步骤 1 界面开发 美颜相机界面构成&#xff1a; 标题 尺寸 关闭方式 位置 可视化 2 创建主函数调用界面方法 3 添加两个面板 一个是按钮面板一个是图片面板 用JPanel 4 添加按钮到按钮面吧【注意&#xff1a;此时要用初始化按钮面板的方法initBtnPanel 并且将按钮添…...

Docker内存芭蕾:优雅调整容器内存的极限艺术

title: “&#x1f4be; Docker内存芭蕾&#xff1a;优雅调整容器内存的极限艺术” author: “Cjs” date: “2025-2-23” emoji: “&#x1fa70;&#x1f4a5;&#x1f4ca;” 当你的容器变成内存吸血鬼时… &#x1f680; 完美内存编排示范 &#x1f4dc; 智能内存管家脚本…...

gitlab初次登录为什么登不上去

今天又写了一次gitlab安装后&#xff0c;第一次登录的问题。 gitlab工作笔记_gitlab默认用户名密码-CSDN博客 因为又掉这个坑里了。 # 为什么第一次登录这么难&#xff1f; 第一是因为gitlab启动的时间很长&#xff0c;有时候以为装错了。 第二是初始密码&#xff0c;如果…...

单链表相关操作(基于C语言)

文章目录 单链表定义版本一(可自己选择是否含头节点)创建单链表打印单链表对单链表进行冒泡排序删除单链表中值为key的节点求单链表表长在单链表位序为i的位置插入新元素e 单链表定义 typedef struct node {int data;struct node* next; }LinkNode,*LinkList;版本一(可自己选择…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...