Leetcode-23-合并k个升序链表

2023-11-13

顺序合并

大家应该对合并两个升序链表很熟悉,它的算法如下:

struct ListNode* MergeList(struct ListNode* head1, struct ListNode* head2)
{
	struct ListNode* cur1 = head1, * cur2 = head2;
	struct ListNode* newhead = NULL, * tail = NULL;
	while (cur1 && cur2)
	{
		if (cur1->val <= cur2->val)
		{
			if (newhead == NULL)
			{
				newhead = tail = cur1;
			}
			else
			{
				tail->next = cur1;
				tail = cur1;
			}
			cur1 = cur1->next;
		}
		else
		{
			if (newhead == NULL)
			{
				newhead = tail = cur2;
			}
			else
			{
				tail->next = cur2;
				tail = cur2;
			}
			cur2 = cur2->next;
		}
	}
	while (cur1)
	{
		if (newhead == NULL)
		{
			newhead = tail = cur1;
		}
		else
		{
			tail->next = cur1;
			tail = cur1;
		}
		cur1 = cur1->next;
	}
	while (cur2)
	{
		if (newhead == NULL)
		{
			newhead = tail = cur2;
		}
		else
		{
			tail->next = cur2;
			tail = cur2;
		}
		cur2 = cur2->next;
	}
	return newhead;
}

由于此题目是将K个升序链表合并,我们可以先将前两个链表合并再与第三个合并…再与第K个合并。

在这里插入图片描述

下面看代码:

struct ListNode* MergeList(struct ListNode* head1, struct ListNode* head2)
{
	struct ListNode* cur1 = head1, * cur2 = head2;
	struct ListNode* newhead = NULL, * tail = NULL;
	while (cur1 && cur2)
	{
		if (cur1->val <= cur2->val)
		{
			if (newhead == NULL)
			{
				newhead = tail = cur1;
			}
			else
			{
				tail->next = cur1;
				tail = cur1;
			}
			cur1 = cur1->next;
		}
		else
		{
			if (newhead == NULL)
			{
				newhead = tail = cur2;
			}
			else
			{
				tail->next = cur2;
				tail = cur2;
			}
			cur2 = cur2->next;
		}
	}
	while (cur1)
	{
		if (newhead == NULL)
		{
			newhead = tail = cur1;
		}
		else
		{
			tail->next = cur1;
			tail = cur1;
		}
		cur1 = cur1->next;
	}
	while (cur2)
	{
		if (newhead == NULL)
		{
			newhead = tail = cur2;
		}
		else
		{
			tail->next = cur2;
			tail = cur2;
		}
		cur2 = cur2->next;
	}
	return newhead;
}

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
	if (listsSize == 0)
	{
		return NULL;
	}
	struct ListNode* newhead = lists[0];
	for (int i = 1; i < listsSize; i++)
	{
		newhead = MergeList(newhead, lists[i]);
	}
	return newhead;
}

分治合并

由于,我们很熟悉两个升序链表的合并,所以这种思路就是,将问题转化为两个升序链表合并。
首先,对lists数组进行分割,分割成等大的两段,分别将这两段中的所有链表合并成为一个链表,最终将两个链表合并。(有种归并排序的感觉。。。)

在这里插入图片描述

下面看代码:

struct ListNode* MergeList(struct ListNode* head1, struct ListNode* head2)
{
	struct ListNode* cur1 = head1, * cur2 = head2;
	struct ListNode* newhead = NULL, * tail = NULL;
	while (cur1 && cur2)
	{
		if (cur1->val <= cur2->val)
		{
			if (newhead == NULL)
			{
				newhead = tail = cur1;
			}
			else
			{
				tail->next = cur1;
				tail = cur1;
			}
			cur1 = cur1->next;
		}
		else
		{
			if (newhead == NULL)
			{
				newhead = tail = cur2;
			}
			else
			{
				tail->next = cur2;
				tail = cur2;
			}
			cur2 = cur2->next;
		}
	}
	while (cur1)
	{
		if (newhead == NULL)
		{
			newhead = tail = cur1;
		}
		else
		{
			tail->next = cur1;
			tail = cur1;
		}
		cur1 = cur1->next;
	}
	while (cur2)
	{
		if (newhead == NULL)
		{
			newhead = tail = cur2;
		}
		else
		{
			tail->next = cur2;
			tail = cur2;
		}
		cur2 = cur2->next;
	}
	return newhead;
}
struct ListNode* mergeKLists1(struct ListNode** lists, int begin, int end)
{
	if (begin >= end)
	{
		return NULL;
	}
	int mid = begin + (end - begin) / 2;
	struct ListNode* ret1 =  mergeKLists1(lists, begin, mid);
	struct ListNode* ret2 = mergeKLists1(lists, mid+1, end);
	return MergeList(ret1, ret2);
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
	if (listsSize == 0)
	{
		return NULL;
	}
	return mergeKLists1(lists, 0, listsSize - 1);
}

循环选结点合并

这种思路,与合并两个升序链表的思想一致,区别就是,每次从listsSize个链表中选出最小的结点。
下面看代码:

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
	if (listsSize == 0)
	{
		return NULL;
	}
	struct ListNode* newhead=NULL, * tail=NULL;
	int flag = 1;
	while (flag)
	{
		int min = 10001;
		int minlog = -1;
		flag = 0;
		for (int i = 0; i < listsSize; i++)
		{
			if (lists[i] == NULL)
			{
				continue;
			}
			if (lists[i]->val < min)
			{
				flag = 1;
				min = lists[i]->val;
				minlog = i;
			}
		}
		if (flag)
		{
			if (newhead == NULL)
			{
				newhead = tail = lists[minlog];
				lists[minlog] = lists[minlog]->next;
			}
			else
			{
				tail->next = lists[minlog];
				tail = lists[minlog];
				lists[minlog] = lists[minlog]->next;

			}
		}
	}
	return newhead;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Leetcode-23-合并k个升序链表 的相关文章

  • 别具一格,原创唯美浪漫情人节表白专辑,(复制就可用)(html5,css3,svg)表白爱心代码(1)

    别具一格 原创唯美浪漫情人节表白专辑 复制就可用 html5 css3 svg 表白爱心代码 1 一 前言 回眸之间 丰盈了岁月 涟漪了思绪 轻轻落笔 不写伤痕 不写仇怨 只写岁月经历领悟后的感恩与体会 说来有点尴尬 我一个奶奶级别的 却从
  • 《大数据导论》理解大数据

    本节书摘来自华章出版社 Spark大数据分析 核心概念 技术及实践 一书中的第1章 第1节 作者托马斯 埃尔 Thomas Erl 瓦吉德 哈塔克 Wajid Khattak 保罗 布勒 Paul Buhler 更多章节内容可以访问云栖社区
  • Unity_Shader_ Properties属性的赋值

    Shader Unlit vf2 in out 输入与输出 Properties MainColor 我是主颜色 Color 1 0 0 1 SubShader Pass CGPROGRAM pragma vertex vert pragm
  • Redis学习 - Tp6配置并使用redis图文详解 小皮面板(三)

    这篇文章主要介绍了Thinkphp6 配置并使用redis的方法 结合实例形式详细分析了Redis的安装 配置以及thinkphp6操作Redis的基本技巧 需要的朋友可以参考下 一 安装redis ThinkPHP内置支持的缓存类型包括f
  • 让ExtJs 2.02的例子也支持换肤

    今天在论坛看到有朋友问我 网站上的换肤功能是如何做的 其实换肤的方法在下载回来的例子中是已经存在的了 但是不知道为什么该功能在ext 2 02下并不可用 要加上换肤功能主要有两个步聚 1 在html页面 每一个例子 的body中间加上以下代
  • 动态软件测试是什么意思,什么是动态测试?

    什么是动态测试 1 概述 动态测试是建立在程序的实行进程傍边 根据对被被测对象内部情况的理解与否 分为黑盒测试盒白盒测试 黑盒测试又称为功能测试 数据驱动测试或基于规格说明的测试 这种测试不消理解被测试对象的内部情况 而依靠需要规格说明中的
  • L2-2 病毒溯源 (25 分)(Dfs详细解析)

    病毒容易发生变异 某种病毒可以通过突变产生若干变异的毒株 而这些变异的病毒又可能被诱发突变产生第二代变异 如此继续不断变化 现给定一些病毒之间的变异关系 要求你找出其中最长的一条变异链 在此假设给出的变异都是由突变引起的 不考虑复杂的基因重
  • curl: (51)Unable to communicate securely with peer

    最近公司做的项目需要联通另一个系统 对方给了个token 测试一下该token是否有效 因为是在Linux上 没有postman 只能通过curl命令发送网络请求 但是实际测试时 由于服务器上有些库的版本比较低 出现各种问题 写篇文章记录一

随机推荐

  • 论文翻译 —— Deep Reinforcement Learning from Human Preferences

    标题 Deep Reinforcement Learning from Human Preferences 文章链接 Deep Reinforcement Learning from Human Preferences blogpost L
  • linux无法引导 rescue 救援模式

    OS版本为 RHEL 7 查看当前引导设备为 dev sda 破坏MBR 执行 dd if dev zero of dev sda bs 446 count 1 重启系统 不能引导 使用光盘进入救援模式 进入troubleshooting
  • IDEA 中设置全局 hook 解决提交代码时 missing changeId 的问题

    背景 IDEA 下载好 Git 项目 安装好 Gerrit 插件后 提交代码时无法将代码 Push 到 Git 仓库 报 missing changeId 的错误 或者说报 rejected by remote 的错误 这是因为 IDEA
  • 判断密码是否合法 (PHP代码函数)

    判断密码是否合法 PHP代码函数 代码来源 Monxin config functions php function is passwd v pattern w 1 100 if preg match pattern v return tr
  • Unity 使用按键控制角色运动

    创建角色 创建一个脚本PlayerController 创建控制器 使用boolean值 脚本 using System Collections using System Collections Generic using UnityEng
  • MySQL实践——MySQL中支持的字符集和排序规则

    一 MySQL字符集概念 1 1 MySQL中的utf8和utf8mb4 我们常说 utf8 字符集表示一个字符需要使用1 4个字节 但是我们常用的一些字符使用1 3个字节就可以表示了 而在 MySQL 中字符集表示一个字符所用最大字节长度
  • 车载以太网新宠SomeIP及其在AutoSAR的应用

    作者结合自身的工作经验介绍SomeIP协议以及在AutoSAR中的实现 汽车不断智能化和网联化的趋势 使得原本的通讯方式 CAN 不堪重负 因此新的需求带来了新的技术 SomeIP应运而生 1 SomeIP的由来 随着汽车智能化和网络化的发
  • Problem E: C语言习题5.21--算法:汉诺塔

    Problem E C语言习题5 21 算法 汉诺塔 Time Limit 1 Sec Memory Limit 64 MB Description 汉诺塔 又称河内塔 问题是印度的一个古老的传说 开天辟地的神勃拉玛在一个庙里留下了三根金刚
  • 基于JSR181标准开发ActiveMQ与Petals ESB交互

    前一节讲到Petals ESB使用JMS连接ActiveMQ到总线 其中因为开发版本的不同和一些细节的配置不到 很难能够正确的使用JMS 如果遇到复杂的JMS需求时 这种方式操作太多 太发太多 而且不容易控制 Petals ESB 4 2支
  • 三列布局方式

    第一种 利用 overflow hidden 的特性 三栏的顺序分别为左 右 中 左右两栏分别设置宽度以及左浮动和右浮动 脱离普通流 这时如果让中间栏高度大于2个边栏会发现两边栏实际上是叠在 main 上面的 因为 main 是块状元素 独
  • 时间序列-异常检测(Anomaly Detection)(一):时间序列的特征工程

    一 介绍 异常检测 Anomaly detection 是目前时序数据分析最成熟的应用之一 定义是从正常的时间序列中识别不正常的事件或行为的过程 有效的异常检测被广泛用于现实世界的很多领域 例如量化交易 网络安全检测 自动驾驶汽车和大型工业
  • word保存为高分辨率图片(word2016)

    word保存为高分辨率图片 word2016 word和ppt转存为jpg或者png等格式的图片时 默认是标准压缩 那么如何实现高分辨率图片保存呢 可按照一下几个步骤来做 亲测有效 第一步 转存为高分辨率pdf 注意要在另存为对话框的选项里
  • python自动化测试教程-最新python版selenium3自动化测试使用说明教程详解

    selenium主要是用来做自动化测试 支持多种浏览器 爬虫中主要用来解决JavaScript渲染问题 模拟浏览器进行网页加载 当requests urllib无法正常获取网页内容的时候 一 声明浏览器对象 注意点一 Python文件名或者
  • 关于ASP.NET MVC与.NET CORE 的区别--小结

    简述关于ASP NET MVC与 NET CORE的区别 1 关于ASP NET 关于MVC 刚开始接触这个技术的时候我经常不理解他们的名字 我相信许多学ASP NET开发人员开始接触MVC应该也和我一样产生很多为什么 也会误认为认为MVC
  • 面面俱到的Java接口自动化测试实战_如何利用TestNG做接口自动化测试?Java+TestNG测试实例分享...

    上一篇自动化测试我们大概了解了测试的目标 测试的技术选型以及搭建平台的目标及需求 也确定了自动化测试方案以testNg作为整个测试流程贯穿的基础支持框架 那么testNg究竟有什么特点 本篇开始我们来详细的学习testNg这个测试框架 为什
  • x86中内存管理寄存器

    x86中内存管理寄存器 处理器提供了4个内存管理寄存器 GDTR LDTR IDTR和TR 用于指定内存分段管理所用系统表的基地址 如图4 2所示 处理器为这些寄存器的加载和保存提供了特定的指令 GDTR LDTR IDTR和TR都是段基址
  • 快手财报,广告、直播、电商齐头并进

    近几年 短视频的热度一直居高不下 抖音 快手更是一度成为了占据人们网络时间最长的App 而随着短视频玩家正在通过发力电商等方式加快自身的商业化步伐 作为短视频领域头部玩家的抖音和快手 更加受到外界关注 近日 快手发布了2022年第四季度及全
  • 实习总结3.1(python函数参数)

    python的函数参数 问的比较多的是 args 和 kwargs的区别 参考文章 定义 f a b c 必选参数 f a b c 0 c为默认参数 f a b c 0 args args可选参数 自动组装为tuple f a b c 0
  • maven打包时找不到程序包,找不到符号

    一 先检查一下打包之前 所依赖的模块是否发生了更改 是否重新已经打包 二 原因是最高级主父工程
  • Leetcode-23-合并k个升序链表

    合并K个升序链表 顺序合并 分治合并 循环选结点合并 顺序合并 大家应该对合并两个升序链表很熟悉 它的算法如下 struct ListNode MergeList struct ListNode head1 struct ListNode