【数据结构与算法】合并链表、链表分割、链表回文结构

主页:HABUO🍁主页:HABUO

🍁如果再也不能见到你,祝你早安,午安,晚安🍁


1.合并链表

题目:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例:

输入:l1 = [1,2,4], l2 = [1,3,4]                          输出:[1,1,2,3,4,4]

输入:l1 = [], l2 = []                                          输出:[]

输入:l1 = [], l2 = [0]                                        输出:[0]

分析:这道题我们用最容易想的迭代的方法实现,就是每次比较两个数的大小,然后相互更改其中的链表节点间的顺序即可,具体思想如下所示:

当然你也可以重新建立一个新的链表,然后这样去比,去尾插新的链表,但是那样空间复杂度变为了O(n)不太好,虽然这个题没有要求,但尽量别这样做。

最正常比较过程如下:

while (list1 && list2)
{if (list1->val < list2->val){if (Tail == NULL){Head = Tail = list1;}else{            Tail->next = list1;Tail = list1;}list1 = list1->next;}else{if (Tail == NULL){Head = Tail = list2;}else{Tail->next = list2;Tail = list2;}list2 = list2->next;}
}

有些细节需要注意,有可能传过来的为NULL,因此我们需要对两个指针进行判断:

if (list1 == NULL)return list2;
if (list2 == NULL)return list1;

又我们的循环条件为:list1 && list2,因此最后是不list1或者list2必须有一个为NULL,但是另一个肯定还没走到最后,因此需要继续:

if (list1)
{Tail->next = list1;Tail = list1;
}
if (list2)
{Tail->next = list2;Tail = list2;
}
return Head;

2.链表分割

题目:现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。

示例:

输入:head = [3,2,1,3,4,5,6], x = 4                     输出:[3,2,1,3,5,6]

分析: 前面我们做的题大多采用的时两个伪指针进行操作的,那这里可不可行呢?因为毕竟是单链表,这里的数据也不是有序的,可能存在的情况错综复杂,搞不好我们就丢失了链表的一些数据😖,那我们能不能反过来想呢?当初我们采取两个伪指针时是因为开辟新的内存空间,空间复杂度上满足不了题目要求了,那这里没有要求,我们能不能开辟两个链表空间,一个存放小于x的,一个存储大于x的,最后将这两个链表连在一起是不是就可以了?答案很显然行得通😮。具体思想见下图:

大致思想就是cur走完整个链表之后将smalltail链到bighead就ok了,但是这里有许多的问题需要处理,smallhead与bighead最开始都有可能为NULL,这是不是要分情况,而且链表的第一个数你有可能比x大是不是还有可能比x小啊,是不是还要分情况,我估计大家想到这里又有似曾相识的感觉了,烦😑,诶,我们之前不是也遇到这种情况了,我们怎么做的?大家还记得吗?是不是设置一个哨兵位啊,因此在本道习题当中我们给smallhead和bighead都设置一个哨兵位头节点,返回的时候我们是不是只需要返回头节点的下一个节点即可。

哨兵位头节点的设定如下:

ListNode* SmallHead = (ListNode*)malloc(sizeof(ListNode));
ListNode* SmallTail = SmallHead;
ListNode* BigHead = (ListNode*)malloc(sizeof(ListNode));
ListNode* BigTail = BigHead;
ListNode* cur = pHead;

最正常情况挪动数据如下:

while(cur)
{if(cur->val < x){ListNode* temp = (ListNode*)malloc(sizeof(ListNode));SmallTail->next = temp;SmallTail = temp;SmallTail->val = cur->val;}else {ListNode* temp = (ListNode*)malloc(sizeof(ListNode));BigTail->next = temp;BigTail = temp;BigTail->val = cur->val;}cur = cur->next;
}

最后返回新的头节点:

BigTail->next = NULL;
SmallTail->next = BigHead->next;
return SmallHead->next;

这里需要注意为什么要加BigTail->next = NULL,因为我们这里都是建立的新的节点,最后一个节点的next是不是不需要再链接其它节点,那它就是随机初始化的一个地址,我们不置空的话,就有可能导致对内存进行非法访问的问题,还有一种是,我们大于的不建立新空间,在原链表进行操作那此时如果不加这一句代码,就有可能导致带环结构,什么意思呢?见下图,因为最开始你3的next放置的就是1那个节点的地址,那你不置空是不是还是那个1的地址,就有可能导致带环,当然如果你释放那个节点的空间,那是不是又造成了非法访问内存的问题

3.链表的回文结构

题目:对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

测试样例:1->2->2->1          返回:true

分析:一般这种链表题它给的都是单链表,你说它坑不坑,就是让你难受😩,但是我劝你别烦,听我娓娓道来😉。前面我们做过了找到中间节点,和反转链表,那这个题能不能用我们前面做过题的一种思想呢?显然是可以的,我们可以找到中间的节点之后,把后半链表逆置,然后从尾和头就可以进行比较了,这就是我们的主体思想可以看下图加以理解,当然也有许多细节需要注意。

对于找到中间节点相信大家都已经很熟悉了,如果还有疑问请翻看本人的前面博客,其中有详细的介绍,在这里我们仅给出代码:

ListNode* fast = A;
ListNode* slow = A;
while (fast != NULL && fast->next != NULL)
{slow = slow->next;fast = fast->next->next;
}

下面是反转链表,前面博客也有详细的介绍,还有不太熟悉的请翻看。我们当时采用了两种方法,一种是三指针法,和头插法,在本题中人家要求了空间复杂度为O(1),因此我们采取三指针法,具体如下:

ListNode* reverse_tail = slow;
ListNode* slow_prev = slow;
slow = slow->next;
ListNode* slow_next = slow->next;
while (slow)
{slow->next = slow_prev;slow_prev = slow;slow = slow_next;slow_next = slow_next->next;
}

相信细心的朋友会看到很多slow->next,是不是存在人家上来给NULL或者一个和两个节点怎么办?因此我们需要在此之前把这几种情况考虑到。具体如下:

if (slow == NULL || slow->next == NULL)
{return false;        
}
if (slow->next == NULL)
{if (A->val == slow->val)return true;elsereturn false;
}

那我们最正常情况的判断就是三个节点以上的判断了,具体如下:

//三个节点以上的判断
while (slow_prev != reverse_tail)
{if (slow_prev->val == A->val){A = A->next;slow_prev = slow_prev->next;}else{return false;}
}

这里需要注意,我们奇偶情况是不是不同,即reverse_tail所处的位置不同啊,奇数是在最中间的位置,偶数是在中间两个位置中的处于下一个的位置。具体情况如下图:

我们进行如下的处理以解决此问题:

//奇偶不同情况的附加条件
if (slow_prev != A)
{if (slow_prev->val == A->val)return true;elsereturn false;
}
return true;

这里格外注意,因为我们的判断条件设置成了 slow_prev != reverse_tail如果设置成了其它,有一定可能造成我们前面所介绍的带环,因为这里无论偶数的2还是奇数的3它的next是不是还是存放的我们之前未改动链表的它的下一个节点的地址啊,如下所示,如果使用了它就造成了带环,要小心!

补充:

Node* Head = NULL, * Tail = NULL;使用这种方式定义时一定要注意前面的变量也需要初始化,它不是跟后面一起的,两个都需要独立的进行操作,在做这几道题的时候,我用了这种定义的方式可把我害惨了😵‍💫。


总结:本篇博客介绍了三道题,这三道题不约而同的用到了我们前面所学到的知识,我相信通过这几道题的应用,我们对前面的知识,无论时反转链表、找中间节点等题型都了然于胸,我们也接触到了一个新题型判断链表的回文结构,相信本篇博客的学习我们受益匪浅!💯


🏋不是每一粒种子都能开花,但播下种子就比荒芜的旷野强百倍🏋

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

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

相关文章

NuGet如何支持HTTP源

今天是2024年11月21号&#xff0c;最近更新了VisualStudio后发现HTTP的包源已经默认禁止使用了&#xff0c;生成时会直接报错。如下图&#xff1a; 官方也明确指出了要想使用HTTP包源的解决办法&#xff0c;这里就简单总结一下。 一、全局配置 1、全局NuGet包的配置文件路径在…

ArcGIS API for Javascript学习

一、ArcGIS API for Javascript 介绍 ArcGIS API for Javascript 是由美国 Esri 公司推出&#xff0c;跟随ArcGIS 9.3 同时发布的&#xff0c;是Esri 基于dojo 框架和 REST 风格实现的一套编程接口。通过 ArcGIS API for Javascript可以对ArcGIS for Server 进行访问&#xff…

React表单联动

Ant Design 1、dependencies Form.Item 可以通过 dependencies 属性&#xff0c;设置关联字段。当关联字段的值发生变化时&#xff0c;会触发校验与更新。 一种常见的场景&#xff1a;注册用户表单的“密码”与“确认密码”字段。“确认密码”校验依赖于“密码”字段&#x…

Spring Boot教程之五:在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序

在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序 IntelliJ IDEA 是一个用 Java 编写的集成开发环境 (IDE)。它用于开发计算机软件。此 IDE 由 Jetbrains 开发&#xff0c;提供 Apache 2 许可社区版和商业版。它是一种智能的上下文感知 IDE&#xff0c;可用于在各种应用程序…

丹摩征文活动|实现Llama3.1大模型的本地部署

文章目录 1.前言2.丹摩的配置3.Llama3.1的本地配置4. 最终界面 丹摩 1.前言 Llama3.1是Meta 公司发布的最新开源大型语言模型&#xff0c;相较于之前的版本&#xff0c;它在规模和功能上实现了显著提升&#xff0c;尤其是最大的 4050亿参数版本&#xff0c;成为开源社区中非常…

STM32F103外部中断配置

一、外部中断 在上一节我们介绍了STM32f103的嵌套向量中断控制器&#xff0c;其中包括中断的使能、失能、中断优先级分组以及中断优先级配置等内容。 1.1 外部中断/事件控制器 在STM32f103支持的60个可屏蔽中断中&#xff0c;有一些比较特殊的中断&#xff1a; 中断编号13 EXTI…

docker run m3e 配置网络,自动重启,GPU等 配置渠道要点

启动命令&#xff1a; docker run -d --restart always -p 6008:6008 --gpus all --name m3e --network fastgpt_fastgpt stawky/m3e-large-api 配置渠道m3e base url要像我这样填写才行&#xff0c;不然回出问题 模型要选m3e 密钥填&#xff1a;sk-aaabbbcccdddeeefffggghhhi…

ubuntu24挂载硬盘记录

1、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff1a; sudo fdisk -l 找到自己硬盘的分区 我的地址/dev/sda 2、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff0c;格式化自己硬盘&#xff1a; sudo mkfs -t ext4 /dev/sda 3、在终端窗口中输入如下…

加菲工具 - 好用免费的在线工具集合

加菲工具 https://orcc.online AI 工具 加菲工具 集合了目前主流的&#xff0c;免费可用的ai工具 文档处理 加菲工具 pdf转word、office与pdf互转等等工具都有链接 图片图标 加菲工具 统计了好用免费的在线工具 编码解码 加菲工具 base64编码解码、url编码解码、md5计算…

网络安全与加密

1.Base64简单说明描述&#xff1a;Base64可以成为密码学的基石&#xff0c;非常重要。特点&#xff1a;可以将任意的二进制数据进行Base64编码结果&#xff1a;所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符&#xff1a;A~Z a~z 0~9 / 对文件进行base64编码…

Easyexcel(6-单元格合并)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09;Easyexcel&#xff08;5-自定义列宽&#xff09;Easyexcel&#xff08;6-单…

三种蓝牙架构实现方案

一、蓝牙架构方案 1、hostcontroller双芯片标准架构 手机里面包含很多SoC或者模块&#xff0c;每颗SoC或者模块都有自己独有的功能&#xff0c;比如手机应用跑在AP芯片上&#xff0c;显示屏&#xff0c;3G/4G通信&#xff0c;WiFi/蓝牙等都有自己专门的SoC或者模块&#xff0…

docker 容器运行Ruoyi-cloud

目录 1&#xff0c;linux系统安装openjdk1.8,mvn,dokcer,node,git 2&#xff0c;拉取代码 1&#xff09;查看gitee仓库地址 2&#xff09;创建/app文件夹&#xff0c;进入app目录 3&#xff09;clone代码 4&#xff09;修改配置文件中nacos地址 3&#xff0c;构建项目 1&…

QT简易项目 数据库可视化界面 数据库编程SQLITE QT5.12.3环境 C++实现

案例需求&#xff1a; 完成数据库插入&#xff0c;删除&#xff0c;修改&#xff0c;查看操作。 分为 插入&#xff0c;删除&#xff0c;修改&#xff0c;查看&#xff0c;查询 几个模块。 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget…

刷题——字符串中的单词数(力扣)

文章目录 一、读题二、思路问题1&#xff1a;解决思路&#xff1a;分割方法&#xff1a;方法1、方法2、 三、代码实现&#xff1a;方法1、方法2、 一、读题 题目来源&#xff1a;https://leetcode.cn/problems/number-of-segments-in-a-string/description/ 首先看例子&#xf…

【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南

文章目录 PyTorch 全面解析2.1 PyTorch 的发展历程2.2 PyTorch 的核心特点2.3 PyTorch 的应用场景 TensorFlow 全面解析3.1 TensorFlow 的发展历程3.2 TensorFlow 的核心特点3.3 TensorFlow 的应用场景 Keras 全面解析4.1 Keras 的发展历程4.2 Keras 的核心特点4.3 Keras 的应用…

什么是 WPF 中的依赖属性?有什么作用?

依赖属性&#xff08;Dependency Property&#xff09;是 WPF 的一个核心概念&#xff0c;它为传统的 .NET 属性提供了增强功能&#xff0c;支持绑定、样式、动画和默认值等功能。通过依赖属性&#xff0c;WPF 提供了一种灵活的数据驱动的方式来处理 UI 属性。 1. 什么是依赖属…

在win10环境部署opengauss数据库(包含各种可能遇到的问题解决)

适用于windows环境下通过docker desktop实现opengauss部署&#xff0c;请审题。 文章目录 前言一、部署适合deskdocker的环境二、安装opengauss数据库1.配置docker镜像源2.拉取镜像源 总结 前言 注意事项&#xff1a;后面docker拉取镜像源最好电脑有科学上网工具如果没有科学上…

2024年11月25日Github流行趋势

项目名称&#xff1a;flux 项目维护者&#xff1a;timudk jenuk apolinario zeke thibautRe项目介绍&#xff1a;FLUX.1模型的官方推理仓库。项目star数&#xff1a;17,381项目fork数&#xff1a;1,229 项目名称&#xff1a;screenshot-to-code 项目维护者&#xff1a;abi cle…

Python 爬虫从入门到(不)入狱学习笔记

爬虫的流程&#xff1a;从入门到入狱 1 获取网页内容1.1 发送 HTTP 请求1.2 Python 的 Requests 库1.2 实战&#xff1a;豆瓣电影 scrape_douban.py 2 解析网页内容2.1 HTML 网页结构2.2 Python 的 Beautiful Soup 库 3 存储或分析数据&#xff08;略&#xff09; 一般爬虫的基…