每日一题---OJ题: 链表的回文结构

news2024/11/27 9:37:32

片头

嗨! 小伙伴们,大家好! 今天我们来一起学习这道OJ题--- 链表的回文结构

嗯...这道题好像不是很难,我们来分析分析

举个例子:

我们可以看到,上图中的两个链表都是回文结构: 即链表的回文结构是指一个链表中的结点值从前往后读和从后往前读都是一样的结构。也就是说,链表的顺序是回文的。

例如,以下链表是回文结构: 1 -> 2 -> 3 -> 2 -> 1

而以下链表不是回文结构: 1 -> 2 -> 3 -> 4 -> 5

那我们怎么判断是不是链表的回文结构呢?

思路1 : 我们可以先找到链表的中间结点,然后反转从这个中间结点开始一直到最后一个结点,并且将反转后的新结点返回,最后定义两个变量,分别去遍历链表的头结点和新结点

比如:

我们定义2个变量,A表示指向链表的头结点(第一个结点),rmid 表示指向反转链表返回的新结点

我们让 A 和 rmid 指向的结点依次比较,如果中途 A 指向结点的值不等于rmid结点指向的值,那么直接退出循环,返回 false;如果比较到 A 和 rmid 都为, 那么返回 true

第一次比较:  A 和 rmid 指向的结点的数据域都相等, 那么指针 A 向后走一步, 指针 rmid 向后走一步

第二次比较: A 和 rmid 指向的结点的数据域都相等, 那么指针 A 向后走一步, 指针 rmid 向后走一步

第三次比较: rmid指针指向NULL, 退出循环, 返回 true 

我们查找链表的中间结点的代码如下:

    //找出中间结点
    struct ListNode* Find(struct ListNode* head){
        struct ListNode* fast = head;            //fast指针指向第一个结点
        struct ListNode* slow = head;            //slow指针指向第一个结点
        while(fast && fast->next){            // 当 fast 并且 fast->next 不为空时,进入循环                   
            slow = slow->next;                //slow指针每次走一步
            fast = fast->next->next;          //fast指针每次走两步
        }
        return slow;                          //返回slow指针指向的结点,就是中间结点
    }

具体的关于链表的中间结点讲解在这里哦, 小伙伴们可以点击查看:  链表的中间结点

我们找到链表的中间结点后,我们就可以反转从这个中间结点开始一直到最后一个结点

反转链表的代码如下:

    //反转链表
    struct ListNode* Reverse(struct ListNode* head){
        struct ListNode* n1 = nullptr;            //定义一个n1指针指向NULL
        struct ListNode* n2 = head;               //定义一个n2指针指向头结点
        struct ListNode* n3 = head->next;         //定义一个n3指针指向头结点的下一个结点

        while(n2 != nullptr){                     //判断n2是否为空
            n2->next = n1;                        //如果n2非空,就把n2的next指针指向n1
            n1 = n2;                              //把n2赋给n1
            n2 = n3;                              //把n3赋给n2
            if(n3){                               //如果n3非空,就让n3指向n3的下一个结点
                n3 = n3->next;
            }
        }
        return n1;                                //最后n2和n3都为空,n1恰好是新链表的头结点
    }

具体的关于反转链表的讲解可以戳这里哦,小伙伴们可以点击查看:  反转链表

好啦,准备工作做好了以后,我们就可以在题目所给的方法里面写代码啦!

首先,我们要定义一个结点指针,用来接收返回过来的中间结点;  其次,我们需要定义另外一个结点指针,用来接收反转链表后的新结点。

将两个指针所指向的结点进行比较,如果它们的数据域不同,说明链表不是回文结构, 则跳出循环, 返回 false ; 如果数据域相同,那么两个指针同时往后走一步,继续比较下一个结点,直到其中一个指针指向NULL, 说明链表是回文结构, 返回 true。

整体代码如下:

class PalindromeList {
  public:
    //找出中间结点
    struct ListNode* Find(struct ListNode* head) {
        struct ListNode* fast = head;            //fast指针指向第一个结点
        struct ListNode* slow = head;            //slow指针指向第一个结点

         // 当 fast 并且 fast->next 不为空时,进入循环
        while (fast && fast->next) {         
            slow = slow->next;         //slow指针每次走一步
            fast = fast->next->next;   //fast指针每次走两步
        }
        return slow;                   //返回slow指针指向的结点,就是中间结点
    }

 //反转链表
    struct ListNode* Reverse(struct ListNode* head){
        //定义一个n1指针指向NULL
        struct ListNode* n1 = nullptr;           
         //定义一个n2指针指向头结点
        struct ListNode* n2 = head;              
        //定义一个n3指针指向头结点的下一个结点
        struct ListNode* n3 = head->next;

        while(n2 != nullptr){       //判断n2是否为空
            n2->next = n1;          //如果n2非空,就把n2的next指针指向n1
            n1 = n2;                //把n2赋给n1
            n2 = n3;                //把n3赋给n2
            if(n3){                 //如果n3非空,就让n3指向n3的下一个结点
                n3 = n3->next;
            }
        }
        return n1;                 //最后n2和n3都为空,n1恰好是新链表的头结点
    }

    bool chkPalindrome(ListNode* A) {
         //定义mid指针,用来接收中间结点
        struct ListNode* mid = Find(A);    
       //定义r指针,用来接收将链表反转后的新结点 
        struct ListNode* r = Reverse(mid); 
        ListNode* pcur = A;

        //当两个指针都不为空时,进入while循环
        while (pcur && r) {
    //如果两个指针指向的结点的数据域不相同,说明链表不是回文结构,那么返回 false
            if (pcur->val != r->val) {
                return false;
            }
    //如果两个指针指向的结点数据域相同,那么继续比较下一个结点
            pcur = pcur->next;
            r = r->next;
        }
        //其中一个指针走向NULL,说明是链表回文结构,返回 true
        return true;
    }
};

片尾

今天我们学习了一道OJ题: 链表的回文结构,里面涉及了查找链表的中间结点以及反转链表等知识,希望看完这篇文章的能对友友们有所帮助 !  !  !

点赞收藏加关注 !   !   !

谢谢大家 !   !   !

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

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

相关文章

蓝桥杯 — —灵能传输

灵能传输 友情链接:灵能传输 题目: 输入样例: 3 3 5 -2 3 4 0 0 0 0 3 1 2 3输出样例: 3 0 3思路: 题目大意:给出一个数组,每次选择数组中的一个数(要求不能是第一个数与最后一个…

Rust语言入门第二篇-Cargo教程

文章目录 Rust语言入门第二篇-Cargo教程一,Cargo 是什么二,Cargo教程Cargo.toml文件src/main.rs 文件构建并运行Cargo项目 Rust语言入门第二篇-Cargo教程 本节提供对cargo命令行工具的快速了解。我们演示了它为我们生成新包的能力,它在包内编…

数据分类分级概念、方法

数据分类分级概念: 根据《GB/T 38667-2020 信息技术-大数据-数据分类指南》的定义,数据分类是根据数据的属性或特征,按照一定的原则和方法进行区分和归类,以便更好地管理和使用数据。数据分类不存在唯一的分类方式,会…

KKVIEW远程远程访问家里电脑

远程访问家里电脑:简易指南与价值所在 在数字化时代,电脑已成为我们日常生活和工作中不可或缺的工具。有时,我们可能在外出时急需访问家中电脑里的某个文件或应用,这时,远程访问家里电脑就显得尤为重要。本文将简要介…

中移物联网 OneOS 操作系统环境搭建和工程创建

一、官网 OneOS Lite是中国移动针对物联网领域推出的轻量级操作系统,具有可裁剪、跨平台、低功耗、高安全等特点,支持ARM Cortex-A和 Cortex-M、MIPS、RISC-V等主流芯片架构,兼容POSIX、CMSIS等标准接口,支持Javascript、MicroPyt…

异构超图嵌入的图分类 笔记

1 Title Heterogeneous Hypergraph Embedding for Graph Classification(Xiangguo Sun , PictureHongzhi Yin , PictureBo Liu , PictureHongxu Chen , PictureJiuxin Cao , PictureYingxia Shao , PictureNguyen Quoc Viet Hung)【WSDM 2021】 2 Co…

【Dijkstra单源最短路径解法】蓝桥杯2022年第十三届决赛真题-出差

我也来贡献一份题解:Dijkstra单源最短路径的简单变式【简单C代码】 这道题的前置知识的Dijkstra单源最短路径算法 如果还没学过,建议去看AcWing算法教程的**图论(2)**中最短路径问题的讲解,u1s1–y总讲的是真的通透! 思路 这道题和单源最短路…

【AI面试】FPN、PANet、SPP、ASPP、Adaptive feature pooling

经常可以看到各个论文发出来,加入的各种trick。这些改进点,一般都是在前人的基础上,进行了一些修改。比如FPN到PANet的改进,就是为了改进前者存在的一些问题。 这里就把这些trick,给汇集到一起,看看他们的发展历史,看看他们之间有什么区别,又是在哪些地方做的改进。这…

C++ stl容器string的底层模拟实现

目录 前言: 1.成员变量 2.构造函数与拷贝构造函数 3.析构函数 4.赋值重载 5.[]重载 6.比较关系重载 7.reserve 8.resize 9.push_back,append和重载 10.insert 11.erase 12.find 14.迭代器 15.流插入,流提取重载 16.swap 17.c_str 18.完…

【Linux】shell脚本实战-if单双分支条件语句详解

if单分支 在所有的编程语言里面&#xff0c;if条件语句几乎是最简单的语句格式&#xff0c;且用途最广。 当if后面的<条件表达式>成立&#xff08;真&#xff09;的时候&#xff0c;就会执行then后面的指令或语句&#xff0c;否则&#xff0c;就会忽略then后面的指令或…

鸿蒙开发学习笔记第一篇--TypeScript基础语法

目录 前言 一、ArkTS 二、基础语法 1.基础类型 1.布尔值 2.数字 3.字符串 4.数组 5.元组 6.枚举 7.unkown 8.void 9.null和undefined 10.联合类型 2.条件语句 1.if语句 1.最简单的if语句 2.if...else语句 3.if...else if....else 语句 2.switch语句 5.函数…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之十 简单视频浮雕画效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之十 简单视频浮雕画效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之十 简单视频浮雕画效果 一、简单介绍 二、简单视频浮雕画效果实现原理 三、简单视频浮雕画效果…

基于微信小程序的短文写作竞赛管理系统

采用技术 基于微信小程序的短文写作竞赛管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringMVCMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 小程序端 登录 首页 竞赛信息界面 竞赛成果界面 学生…

2024个人动态线条导航HTML源码

源码介绍 2024个人导航HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 源码下载 2024个人导航HTML源码

Django Rest Framework的序列化和反序列化

Django Rest Framework的序列化和反序列化 目录 Django Rest Framework的序列化和反序列化Django传统序列化Django传统反序列化安装DRF序列化器serializers序列化反序列化反序列化保存instance和data CBV和APIView执行流程源码解析CBV源码分析APIView源码分析 DRF的Request解析…

KVM部署

1、检查虚拟化支持 首先&#xff0c;确认你的系统处理器支持硬件虚拟化&#xff0c;在Linux终端中&#xff0c;使用以下命令&#xff1a; egrep -c (vmx|svm) /proc/cpuinfo2、安装KVM及其工具 yum update yum install qemu-kvm libvirt libvirt-python libguestfs-tools vi…

FPGA - 以太网UDP通信(二)

一&#xff0c;引言 前文链接&#xff1a;FPGA - 以太网UDP通信&#xff08;一&#xff09; 在上文章中介绍了以太网简介&#xff0c;以太网UDP通信硬件结构&#xff0c;以及PHY芯片RGMII接口-GMII接口转换逻辑&#xff0c;接下来介绍UDP通信结构框图以及数据链路层&#xff…

政安晨:【Keras机器学习实践要点】(二十六)—— 内卷神经网络

目录 简介 设置 卷积 演变 测试逆卷积层 图像分类 获取 CIFAR10 数据集 数据可视化 卷积神经网络 逆向传播神经网络 比较 损失图和准确率图 可视化卷积核 结论 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Ke…

从 SQLite 3.5.9 迁移到 3.6.0(二十一)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;从 SQLite 3.4.2 迁移到 3.5.0&#xff08;二十&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 ​SQLite 版本 3.6.0 &#xff08;2008-07-16&#xff09; 包含许多更改。按照惯例 SQLite项目&#xff…

FPGA在医疗的应用,以4K医疗内窥镜为例

前言 随着技术的发展&#xff0c;医学影像作为科学技术的主要成就之一&#xff0c;在无创诊断和治疗领域已经有了多种应用。其中一个应用是内窥镜&#xff0c;在20世纪90年代&#xff0c;当利用电荷耦合装置将图像传输到显示器上成为可能时&#xff0c;内窥镜变得更加广泛。为…