每日一题——回文链表
回文链表
题目链接
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GvuT2cBE-1691217006189)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230805111025312.png)]](https://img-blog.csdnimg.cn/b090622b8263425eabdfd9e393f71115.png)
回文结构即字符串正序逆序完全一致,如“1 2 3 4 3 2 1”,那么我们就要想办法同时比较链表头和链表尾的元素,看其是否相等。
下面介绍一种最常用的方法:
思路
如果我们仔细观察回文结构,就会得到一个结论:
将一个回文结构从正中间分隔,再将后半部分逆序,那么前半部分就一定等于后半部分。
我们可以分链表长度为奇数和偶数讨论:
当长度为偶数:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJGE5AkL-1691217006190)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230805132642866.png)]](https://img-blog.csdnimg.cn/41c32e8a3bb34560adbaa5b7789615d0.png)
当长度为奇数:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tnzqfbdq-1691217006190)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230805132749391.png)]](https://img-blog.csdnimg.cn/8c78f72d1aec4a4d8d3f0d47126e3cf8.png)
- 那么**,第一步就先要得到链表的中间节点。我们可以用快慢指针**来实现:
定义两个指针fast、slow,同时指向链表头,slow每次走一个,fast每次走两个节点,当fast->next == NULL 或者 fast == NULL时,slow就走到中间节点了
struct ListNode* slow = head;
struct ListNode* fast = head;while (fast && fast->next)
{slow = slow->next;fast = fast->next->next;
}
- 第二步,就是反转以
slow节点为头的链表,如果对单链表反转还不太了解的朋友,建议先看看👉反转单链表
struct ListNode* reverseList(struct ListNode* head)
{if (head == NULL)return NULL;struct ListNode* newHead = (struct ListNode*)malloc(sizeof(struct ListNode));newHead->next = head;struct ListNode* cur = head;while (cur->next){struct ListNode* curNext = cur->next;cur->next = curNext->next;curNext->next = newHead->next;newHead->next = curNext;}struct ListNode* retHead = newHead->next;free(newHead);return retHead;
}
- 第三步,我们用指针
mid来接受slow后链表反转过后的头,接下来,从原来链表的头和mid开始比较,只要遇到不相等的情况,就返回false,否则返回true。
struct ListNode* mid = reverseList(slow->next);
struct ListNode* cur1 = head;
struct ListNode* cur2 = mid;while (cur1 && cur2)
{if (cur1->val != cur2->val){return false;}cur1 = cur1->next;cur2 = cur2->next;
}return true;
- 最后一步,**在返回之前,需要将链表还原,**毕竟在现实生活中,没有人想再调用这个函数时改变原来的链表结构。但是,如果我们就按上面的操作进行还原,那么就会出现一系列的问题,我们拿下图说明
判断过后,链表的结构是这样的:

如果我们要将链表还原,那么问号处的节点的后面应该链接到reverseList(mid)的返回值,但问题是之前我们并没有保存问号处的节点。所以,我们可以对找到链表中间节点这一操作进行改进:
struct ListNode* slow = head;
struct ListNode* fast = head;while (fast->next && fast->next->next)
{slow = slow->next;fast = fast->next->next;
}
这样slow就会停留在问号处的位置,反转链表的时候就反转以slow->next为头的链表就行了
实现代码
struct ListNode* reverseList(struct ListNode* head) //反转链表
{if (head == NULL)return NULL;struct ListNode* newHead = (struct ListNode*)malloc(sizeof(struct ListNode));newHead->next = head;struct ListNode* cur = head;while (cur->next){struct ListNode* curNext = cur->next;cur->next = curNext->next;curNext->next = newHead->next;newHead->next = curNext;}struct ListNode* retHead = newHead->next;free(newHead);return retHead;
}bool isPalindrome(struct ListNode* head){struct ListNode* slow = head;struct ListNode* fast = head;while (fast->next && fast->next->next) //找到中间节点的前一个节点{slow = slow->next;fast = fast->next->next;}//反转以中间节点为头的链表//将返回值赋给midstruct ListNode* mid = reverseList(slow->next); struct ListNode* cur1 = head;struct ListNode* cur2 = mid;bool ret = true; //设置返回值while (cur1 && cur2){if (cur1->val != cur2->val){ret = false; //只要出现不相等的情况,就将返回值设为false,推出比较break;}cur1 = cur1->next;cur2 = cur2->next;}//还原链表mid = reverseList(mid);slow->next = mid;//返回return ret;
}
相关文章:
每日一题——回文链表
回文链表 题目链接 回文结构即字符串正序逆序完全一致,如“1 2 3 4 3 2 1”,那么我们就要想办法同时比较链表头和链表尾的元素,看其是否相等。 下面介绍一种最常用的方法: 思路 如果我们仔细观察回文结构,就会得到一…...
OPENCV C++(一) 二进制和灰度原理 处理每个像素点值的方法
#include <opencv2/opencv.hpp> using namespace std; using namespace cv;必须包含的头文件! 才能开始编写代码 读取相片 一般来说加个保护程序 不至于出error和卡死 Mat image imread("test.webp"); //存放自己图像的路径 if (image.empty()){p…...
Python GUI编程(Tkinter)
Python GUI编程(Tkinter) Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows …...
K8S简介
目录 前言K8S 简介K8S 是什么作用Kubernetes 主要功能如下:Kubernetes 集群架构与组件 核心组件Master 组件Kube-apiserverKube-controller-managerKube-scheduler配置存储中心 etcd Node 组件KubeletKube-Proxydocker 或 rocket Kubernetes 核心概念PodPod控制器La…...
策略模式——算法的封装与切换
1、简介 1.1、概述 在软件开发中,常常会遇到这种情况,实现某一个功能有多条途径。每一条途径对应一种算法,此时可以使用一种设计模式来实现灵活地选择解决途径,也能够方便地增加新的解决途径。为了适应算法灵活性而产生的设计模…...
c++转换构造,拷贝构造,operator=
c转换构造,拷贝构造,operator 一.转换构造 定义一个类 class CTest { public:int m_a;CTest(int m_a):m_a(0){} };在主函数中定义对象 CTest tes1(1); CTest tes2 5;//我们发现这种定义对象的方式不符合常理,这里其实是发生了隐式类型转…...
支付宝蜻蜓设备abs调试
蜻蜓设备系统日志调试 1、蜻蜓设备进入开发者模式 长按关键键直到屏幕上出现设置按钮,点击设置按钮,选择关于本机,找到系统版本,连续点击8次,选择进入调试模式 2、找到小程序容器,连续点击8次࿰…...
论memset的时间代价
论memset的时间代价 众所周知,memset是一个常用的数组赋值方式,几乎每个OI player全都使用过,但是这个函数从来不要脸,也不给你脸。 大家耳顺能详的几个例子: ①memset(a,0,sizeof(a));把a全赋值成0。 ②memset(a,…...
linux下绑定进程到指定CPU的操作方法
taskset简介 # taskset Usage: taskset [options] [mask | cpu-list] [pid|cmd [args...]] Show or change the CPU affinity of a process. Options: -a, --all-tasks operate on all the tasks (threads) for a given pid -p, --pid operate on ex…...
springboot+maven插件调用mybatis generator自动生成对应的mybatis.xml文件和java类
mybatis最繁琐的事就是sql语句和实体类,sql语句写在java文件里很难看,字段多的表一开始写感觉阻力很大,没有耐心,自动生成便成了最称心的做法。自动生成xml文件,dao接口,实体类,虽一直感觉不太优…...
C# 根据前台传入实体名称,动态查询数据
前言: 项目中时不时遇到查字典表等数据,只需要返回数据,不需要写其他业务,每个字典表可能都需要写一个接口给前端调用,比较麻烦,所以采用下面这种方式,前端只需传入实体名称即可,例…...
Netty入门学习
目录 为什么要学习nettynetty学习导图学习netty前需要知道的知识I/O模型主要I/O模型 netty框架的整体结构netty的逻辑架构网络通信层事件调度层服务编排层 为什么要学习netty Netty是由JBOSS提供的一个Java开源框架,现为Github上的独立项目。Netty本质是一个NIO框架…...
代客泊车对HUT功能交互规范
目录 1. 版本记录... 7 2. 文档范围和控制... 8 2.1 目的/范围... 8 2.2 文档冲突... 8 2.3 文档授权... 8 2.4 文档更改控制... 8 3. 系统组成... 9 3.1 IPAS系统(环视和超声波雷达)...…...
mysql的update_time
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50) NOT NULL,age INT,update_time TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间 );具体解释如下: DEFAULT CURRENT_TIMESTAMP: 这部分表示当插入…...
避免安装这5种软件,手机广告频繁弹窗且性能下降
在我们使用手机的日常生活中,选择合适的应用软件对于保持良好的使用体验至关重要。然而,有些软件可能会给我们带来不必要的麻烦和困扰。特别是那些频繁弹窗广告、导致手机性能下降的应用程序,我们应该尽量避免安装它们。 首先第一种…...
kafka-事务
1. 事务的5个API // 1初始化事务 void initTransactions();// 2开启事务 void beginTransaction() throws ProducerFencedException;// 3在事务内提交已经消费的偏移量(主要用于消费者) void sendOffsetsToTransaction(Map<TopicPartition, OffsetAn…...
【安装】阿里云轻量服务器安装Ubuntu图形化界面(端口号/灰屏问题)
阿里云官网链接 https://help.aliyun.com/zh/simple-application-server/use-cases/use-vnc-to-build-guis-on-ubuntu-18-04-and-20-04 网上搜了很多教程,但是我没在界面看到有vnc连接,后面才发现官网有教程。 其实官网很详细了,不过这里还是…...
Python 扩展 快捷贴士:os模块下的创建目录的方式
Python3 os.makedirs() 方法 概述 os.makedirs() 方法用于递归创建多层目录。 如果子目录创建失败或者已经存在,会抛出一个 OSError 的异常,Windows上Error 183 即为目录已经存在的异常错误。 如果第一个参数 path 只有一级,即只创建一层目…...
Hi3798MV200 恩兔N2 NS-1 (一): 设备介绍和刷机说明
目录 Hi3798MV200 恩兔N2 NS-1 (一): 设备介绍和刷机说明Hi3798MV200 恩兔N2 NS-1 (二): HiNAS海纳思使用和修改Hi3798MV200 恩兔N2 NS-1 (三): 制作 Ubuntu rootfsHi3798MV200 恩兔N2 NS-1 (四): 制作 Debian rootfs 介绍 恩兔N2是一个家庭存储的系列产品, NS-1 是其中体积…...
redis缓存雪崩和缓存击穿
目录 缓存雪崩 解决方案: 缓存击穿 解决方案 缓存雪崩 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。 解决方案: u 给不同的 Key 的 TTL 添加随机值 u 利用 Redis …...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...
