1. 题目描述(基础要求)

给定一个链表的头节点head,请判断该链表是否为回文结构。 例如: 1->2->1,返回true。 1->2->2->1,返回true。15->6->15,返回true。 1->2->3,返回false。

2. 思路

如果对空间复杂度没有要求的话,我们可以借助辅助空间.我们借助一个STL的stack将我们的value放到栈当中,然后对比的时候从栈顶弹出元素,如果有一个不相等则返回false,否则返回true; 进一步的话我们可以使用二个指针,一个快指针,一个慢指针,快指针一次走二步,慢指针一次走一步,当快指针到达终点的时候,慢指针刚好到达中点,然后我们将整个链表分成左和右二个部分,然后我们将右半部分压栈进行对比,这样就会节省一半的空间.

3. 进阶版本

如果程序进一步要求:如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。也就是不准使用辅助空间,这个时候怎么办了?

  1. 首先用一个快指针,一个慢指针来遍历链表。快指针每次走两步,慢指针每次走一步。等到快指针遍历完链表,慢指针就正好停留在链表的中央。
  2. 将链表的后半部分进行反转。
  3. 将链表的前半部分与后半部分逐个比对。若都相同,则为回文链表,否则不是。
  4. 将反转之后右半部分的链表进行恢复.

4. 代码

4.1 程序说明:

这里我们实现了三个函数进行判断是否为回文链表,分别是:

  1. isPalindrome1 使用O(N)O(N)O(N)辅助空间,对应基础版本.
  2. isPalindrome2 使用O(N/2)O(N/2)O(N/2)辅助空间,对应基础版本.
  3. isPalindrome3 使用O(1)O(1)O(1)辅助空间,对应进阶版本.
#include <iostream>
#include <vector>
#include <stack>struct ListNode {int val;struct ListNode* next;ListNode(int x) :val(x), next(nullptr) {}
};
// need n extra space
bool isPalindrome1(ListNode* head) {std::stack<int> my_node_value;ListNode* curNode = head;while (curNode != nullptr) {my_node_value.push(curNode->val);curNode = curNode -> next;}while (head!= nullptr) {if (head -> val != my_node_value.top()) {return false;} else {head = head -> next;my_node_value.pop();}}return true;
}// need n/2 extra space
bool isPalindrome2(ListNode* head) {if (head == nullptr || head -> next == nullptr) {return true;}std::stack<int> my_node_value;ListNode* slowNode = head -> next;ListNode* fastNode = head;while (fastNode -> next != nullptr && fastNode -> next -> next != nullptr) {    // get the middle nodeslowNode = slowNode -> next;fastNode = fastNode -> next -> next;}while (slowNode != nullptr) {my_node_value.push(slowNode -> val);slowNode = slowNode -> next;}while (!my_node_value.empty()) {   // here we can't use the condition: head != nullptrif (head -> val != my_node_value.top()) {return false;break;} else {head = head -> next;my_node_value.pop();}}return true;
}// need O(1) extra space
bool isPalindrome3(ListNode* head) {if (head == nullptr || head -> next == nullptr) {return true;}ListNode* n1 = head;    // slow pointerListNode* n2 = head;    // fast pointerwhile (n2 -> next != nullptr && n2 -> next -> next != nullptr) {n1 = n1 -> next;n2 = n2 -> next  -> next;}n2 = n1 -> next;    // n2 now is the first node in the second listn1 -> next = nullptr;ListNode* n3 = nullptr;    // A ListNode to store the last node in the second listwhile (n2 != nullptr) {n3 = n2 -> next;n2 -> next = n1;n1 = n2;n2 = n3;}n3 = n1;    // here n1 is the last node in the second list, we need to store the last node to reconvern2 = head;  // compare the first and the second listwhile (n1 != nullptr && n2 != nullptr) {if (n1 -> val != n2 -> val) {return false;break;} else {n1 = n1 -> next;n2 = n2 -> next;}}n1 = n3 -> next;    // here we recover the second list to the origin ordern3 -> next = nullptr;   // the origin last node next poiter is nullptrwhile (n1 != nullptr) {n2 = n1 -> next;n1 -> next = n3;n3 = n1;n1 = n2;}return true;}void printList(ListNode* pHead) {while (pHead != nullptr) {std::cout << pHead -> val << ",";pHead= pHead -> next;}std::cout << "\n";
}int main()
{ListNode* pHead = new ListNode(1);pHead -> next = new ListNode(2);pHead -> next -> next = new ListNode(1);std::cout << "origin list is:" << std::endl;printList(pHead);bool is_palindrome = isPalindrome3(pHead);if (is_palindrome) {std::cout << "is palindrome" << std::endl;} else {std::cout << "not palindrome" << std::endl;}return 0;
}

这里的话我们列举了二种情况:一种是1 2 1 结构,另外一种是 1 2 3 结构,我们都得到了正确的结果,这里以isPalindrome3函数为例子.

实现isPalindrome3函数还是有点复杂的,这个节点的指向有点绕晕了.

C++判断一个链表是否为回文结构相关推荐

  1. 算法练习day9——190327(“之” 字形打印矩阵、在行列都排好序的矩阵中找数、打印两个有序链表的公共部分、判断一个链表是否为回文结构)

    1."之" 字形打印矩阵 [题目] 给定一个矩阵matrix, 按照"之" 字形的方式打印这个矩阵, 例如: 1 2 3 4 5 6 7 8 9 10 11 1 ...

  2. 数据结构与算法之打印两个有序链表公共部分和判断一个链表是否具有回文结构

    数据结构与算法之打印两个有序链表公共部分和判断一个链表是否具有回文结构 目录 打印两个有序链表公共部分 判断一个链表是否具有回文结构 1. 打印两个有序链表公共部分 1.问题描述 思路:Node1和N ...

  3. 牛客题霸 [判断一个链表是否为回文结构] C++题解/答案

    判断一个链表是否为回文结构 题目描述 给定一个链表,请判断该链表是否为回文结构. 题解: 直接将链表内的数据存入string中,然后从两端开始向中间判断即可 代码: /*** struct ListN ...

  4. c语言数据结构判断回文数,C++数据结构与算法之判断一个链表是否为回文结构的方法...

    本文实例讲述了C++判断一个链表是否为回文结构的方法.分享给大家供大家参考,具体如下: 题目: 给定一个链表头节点head,请判断是否为回文结构 例如: 1->2->1 true 1-&g ...

  5. 判断一个链表是否为回文结构【Java实现】

    题目:给定一个链表的头节点head,请判断该链表是否为回文结构. 如:1 2 1 返回true 1 2 2 1 返回true 1 2 3 返回false 思路一: 利用栈,从左到右遍历链表,然后将每一 ...

  6. 刷题日记-判断一个链表是否为回文结构

    判断一个链表是否为回文结构 描述 给定一个链表,请判断该链表是否为回文结构. 回文是指该字符串正序逆序完全一致. 数据范围: 链表节点数 0≤n≤10510^5105,链表中每个节点的值满足∣val∣ ...

  7. 判断一个链表是否为回文结构

    package class_03;import java.util.Stack;/*** * 判断一个链表是否为回文结构[题目] 给定一个链表的头节点head,请判断该链表是否为回文结构. 例如: 1 ...

  8. (十三)判断一个链表是否是回文结构

    判断一个链表是否是回文结构 判断一个链表是否是回文结构 栈实现 栈+快慢指针 有限个变量 判断一个链表是否是回文结构 [题目]给定一个单链表的头结点,请判断该链表是否为回文结构 [要求]如果链表长度为 ...

  9. 判断一个链表是否为回文结构-Java:解法三

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net package live.every.day.Pro ...

  10. NC96 判断一个链表是否为回文结构

    NC96 判断一个链表是否为回文结构 描述 给定一个链表,请判断该链表是否为回文结构. 示例1 输入: [1] 复制 返回值: true 复制 示例2 输入: [2,1] 复制 返回值: false ...

最新文章

  1. MySQL的binary类型操作
  2. 日语输入法电脑版_日语输入法下载及使用教程【建议收藏】
  3. Hibernate开发中常见错误总结
  4. 如何申请一份iOS工作
  5. python爬取mysql_Python如何爬取51cto数据并存入MySQL
  6. 我可能不适合做前端,你呢?
  7. 一小时后关机_固始一女孩被塑料框“咬手” ,近1个小时后…
  8. pytorch forward
  9. WINDOWS编译OpenJDK8的问题及解决办法
  10. java最长同值路径_力扣——最长同值路径
  11. 基于C语言的小游戏合集
  12. php bi系统,bi系统是什么系统
  13. 2020软件测试最新视频教程大合集汇总
  14. C语言实现蔡勒公式求周几
  15. 音频(三)音色与spectrum 频谱图
  16. r语言如何计算t分布临界值_R语言系列第四期:R语言单样本双样本差异性检验...
  17. Acwing-872. 最大公约数
  18. html页面退格代码,HTML中的退格键
  19. 以后给孩子起名字不用发愁了
  20. 解决导入MySQL数据库提示“Unknown character set: ‘utf8mb4‘“错误

热门文章

  1. 未来的计算机 展望未来作文,以展望未来为题的作文(精选4篇)
  2. 沉默-具有艺术魅力-DHV(展示高价值-会装逼)的程序员如何泡到妹子
  3. 插入数据提示:1366 - Incorrect string value: ‘lxE7\x8F\xAD’ for column ‘des‘ at row 1
  4. 基于大数据重庆市气象数据分析 计算机毕设源码24928
  5. 【Gmail to Office365 邮箱迁移踩坑总结】日历
  6. python关于类的slots属性
  7. 2008年个人工作总结
  8. 卡哇伊非主流美女教程(恶搞版)
  9. CSS3动画 3D基础知识
  10. poi 最基本的方法 ,浏览器导出excel