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

片头

嗨! 小伙伴们,大家好! 今天我们来一起学习这道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题: 链表的回文结构,里面涉及了查找链表的中间结点以及反转链表等知识,希望看完这篇文章的能对友友们有所帮助 !  !  !

点赞收藏加关注 !   !   !

谢谢大家 !   !   !

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

春秋云境:CVE-2022-32991[漏洞复现]

从CVE官网查询该漏洞相关信息 该漏洞是由于welcome.php中的eid参数包含了SQL注入漏洞 则我们的目标就在于寻找welcome.php地址以及相关的可注入eid参数 开启靶机 先在页面正常注册、登录一个账号。密码随便填 进入了home目录,这里有三个话题可以选择开启 随便选…

word批量修改表格样式

利用宏,批量选中表格,然后利用段落和表设计来操作。 利用宏,批量选中表格,参考百度安全验证段落,表格里面的内容有空格,应该是有缩进,在段落中去掉缩进,即缩进-特殊,选择…

Next.js 14 App Router引入 farmer-motion 初始化异常解决,顺带学点知识

前言 farmer-motion 是一个非常好用的动画库,当然用来做组件切换和路由切换过渡更不在话下。 记录一下,Next.js 14 App Router 下引入初始化异常的解决姿势,顺带扯一下 next.js 的知识点; 问题 过渡组件代码 我们拿 farmer-m…

https证书是什么,怎么申请

https证书的名称有很多,其本名是SSL/TLS数字证书,本意是实现https访问的证书,故而很多人会称之为https证书,又因为其需要部署于域名服务器之上,所以也有人称之为域名证书。 所以https证书又名SSL证书、域名证书等。 h…

SPN的相关利用(上)

什么是SPN 服务主体名称(SPN)是服务实例,可以理解为一个服务,比如mssql,http等等的唯一标识符。如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的 SPN,Kerberos 身份验证使用 SPN 将服务实例与服务登录…

深入理解 pytest Fixture 方法及其应用

当涉及到编写自动化测试时,测试框架和工具的选择对于测试用例的设计和执行非常重要。在Python 中,pytest是一种广泛使用的测试框架,它提供了丰富的功能和灵活的扩展性。其中一个很有用的功 能是fixture方法,它允许我们初始化测试环…

Eland上传bge-large-zh-v1.5向量化模型到ElasticSearch中

最近需要做一些向量检索,试试ES 一、准备 系统:MacOS 14.3.1 ElasticSearch:8.13.2 Kibana:8.13.2 本地单机环境,无集群,也不基于Docker BGE是一个常见的文本转向量的模型,在很多大模型RAG应…

Objective-C网络数据捕获:使用MWFeedParser库下载Stack Overflow示例

概述 Objective-C开发中,网络数据捕获是一项常见而关键的任务,特别是在处理像RSS源这样的实时网络数据流时。MWFeedParser库作为一个优秀的解析工具,提供了简洁而强大的解决方案。本文将深入介绍如何利用MWFeedParser库,以高效、…

【Linux系统编程】第五弹---基本指令(三)

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、grep指令 2、zip/unzip指令 3、tar指令 4、bc指令 5、uname指令 6、重要的几个热键 7、拓展指令 总结 1、grep指令 …

HTML学习笔记:链接target属性

关于target的使用&#xff1a; <a href"https://www.baidu.com" target"_parent">网址链接</a>其中关于target四个特殊目标的理解&#xff0c;W3school上的解释为&#xff1a; HTML 标签的 target 属性 其中_black和_self两个属性很好理解&…

谷粒商城part2——环境篇

这里是过来人的学习建议&#xff1a; 1、如有条件电脑内存至少16G起步&#xff0c;条件进一步加个屏幕&#xff0c;条件更进一步租一台至少4G内存的X86架构云服务器&#xff0c;所有部署的东西全扔云服务器上 2、P16&#xff0c;P17没法搭起来的建议照着rerenfast的github上的教…

一文了解OCI标准、runC、docker、contianerd、CRI的关系

docker和contanerd都是流行的容器运行时&#xff08;container runtime&#xff09;&#xff1b;想讲清楚他们两之间的关系&#xff0c;让我们先从runC和OCI规范说起。 一、OCI标准和runC 1、OCI&#xff08;open container initiative&#xff09; OCI是容器标准化组织为了…

数字化实践案例丨捷安高科项目管理系统打造项目与业务双联动

30秒快读 为了解决郑州捷安高科股份有限公司&#xff08;简称&#xff1a;捷安高科&#xff09;公司规模化和业务扩展进程中带来的系列管理痛点&#xff0c;如项目的成本收益不透明、跨部门协调困难、人力资源配置和投入产出不清晰等&#xff0c;捷安高科启动了项目管理系统建设…

【Pytorch】Conv1d

conv1d 先看看官方文档 再来个简单的例子 import torch import numpy as np import torch.nn as nndata np.arange(1, 13).reshape([1, 4, 3]) data torch.tensor(data, dtypetorch.float) print("[data]:\n", data) conv nn.Conv1d(in_channels4, out_channels1…

常见面试算法题-数组二叉数

■ 题目描述 【数组二叉树】 二叉树也可以用数组来存储&#xff0c;给定一个数组&#xff0c;树的根节点的值存储在下标1&#xff0c;对于存储在下标N的节点&#xff0c;它的左子节点和右子节点分别存储在下标2*N和2*N1&#xff0c;并且我们用值-1代表一个节点为空。 给定一…

Interpretable3D:一种用于3D点云的即时可解释分类器

Interpretable3D&#xff1a;一种用于3D点云的即时可解释分类器 paper github

【病毒分析】phobos家族2700变种加密器分析报告

1.样本信息 ⽂件名Fast.exeSHA2563c95bd8e14f6aa92e94ec3318d23a8cc34192259MD528c6c0b4f54912ec73c9bfeb3f2a8f07运行平台Windows 2.感染迹象 2.1 文件结构分析 整体文件大小为200k,把冗余数据去掉,发现仍然可以运行,大小变为56k。与phobos家族的标准一致。 2.1.1 勒索信 …

python笔记 | 哥德巴赫猜想

哥德巴赫猜想&#xff1a;每个不小于6的偶数都可以表示成两个素数之和。 素数&#xff1a;只能被1和自身整除的正整数。就是大于1且除了1和它本身之外没有其他因数的数。例如&#xff0c;2、3、5、7、11等都是素数&#xff0c;而4、6、8、9等则不是素数。 下面这段Python代码…

Day 16 Linux服务管理和日志管理

服务管理 启动服务&#xff1a;systemctl start 服务名 停止服务&#xff1a;systemctl stop 服务名 重启服务&#xff1a;systemctl restart 服务名 重新加载配置文件&#xff1a;systemctl reload 服务名&#xff08;期间并不停止服务进程&#xff09; 查看服务运行状态…

十、OOP面向对象程序设计(五)

1、什么是接口以及接口的运用 1)接口定义 Java接口(Interface),是一些列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能。) 2)接口定义的一般形式 修饰符:…