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

2024-04-12 06:04

本文主要是介绍每日一题---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指针指向NULLstruct ListNode* n2 = head;               //定义一个n2指针指向头结点struct ListNode* n3 = head->next;         //定义一个n3指针指向头结点的下一个结点while(n2 != nullptr){                     //判断n2是否为空n2->next = n1;                        //如果n2非空,就把n2的next指针指向n1n1 = n2;                              //把n2赋给n1n2 = n3;                              //把n3赋给n2if(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指针指向NULLstruct ListNode* n1 = nullptr;           //定义一个n2指针指向头结点struct ListNode* n2 = head;              //定义一个n3指针指向头结点的下一个结点struct ListNode* n3 = head->next;while(n2 != nullptr){       //判断n2是否为空n2->next = n1;          //如果n2非空,就把n2的next指针指向n1n1 = n2;                //把n2赋给n1n2 = n3;                //把n3赋给n2if(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) {//如果两个指针指向的结点的数据域不相同,说明链表不是回文结构,那么返回 falseif (pcur->val != r->val) {return false;}//如果两个指针指向的结点数据域相同,那么继续比较下一个结点pcur = pcur->next;r = r->next;}//其中一个指针走向NULL,说明是链表回文结构,返回 truereturn true;}
};

片尾

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

点赞收藏加关注 !   !   !

谢谢大家 !   !   !

这篇关于每日一题---OJ题: 链表的回文结构的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/896297

相关文章

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

深入手撕链表

链表 分类概念单链表增尾插头插插入 删尾删头删删除 查完整实现带头不带头 双向链表初始化增尾插头插插入 删查完整代码 数组 分类 #mermaid-svg-qKD178fTiiaYeKjl {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-

建立升序链表

题目1181:遍历链表 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2744 解决:1186 题目描述: 建立一个升序链表并遍历输出。 输入: 输入的每个案例中第一行包括1个整数:n(1<=n<=1000),接下来的一行包括n个整数。 输出: 可能有多组测试数据,对于每组数据, 将n个整数建立升序链表,之后遍历链表并输出。 样例输

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结,删除链表节点问题使用到列表,哈希表,递归比较容易超时,我觉得使用计数排序比较稳,处理起来也不是很难。 1. 力扣3217:从链表中移除在数组中的节点 1.1 题目: 给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后,返回修改后的链表的头节点。 示例 1: 输入: nums = [1,2,3], head = [1,2,3,

c++ 链表详细介绍

链表是数据结构的一种,由节点组成,每个节点包含数据和指向下一个节点的指针。链表在C++中的实现可以是单链表、双链表或循环链表。以下是链表的详细介绍: 1. 单链表 结构: 节点(Node):每个节点包含数据和一个指针(next),指向链表中的下一个节点。 示例结构: struct Node {int data;Node* next;Node(int d) : data(d), next(