如何判断一个单向链表是否为回文链表(Palindrome Linked List)
题目:给定一个单向链表,判断它是不是回文链表(即从前往后读和从后往前读是一样的)。原题见下图,还要求了O(n)的时间复杂度O(1)的空间复杂度。
我的思考:
1,一看到这个题目,大脑马上想到的解决方案就是数组。遍历链表,用数组把数据存下来,然后再进行一次遍历,同时用数组反向地与之比较,这样就可以判断是否回文。这个方法时间复杂度是O(n),达到了要求,然而空间复杂度显然不满足要求。所以,开数组这一类的方法显然不是最佳的。
2,既然要满足O(1)的空间复杂度,我就想到了用一个变量来存储这些数据,恰好题目给出的数据也是整型。具体思路就是用一个long int:sum来存储这些数据,第一次遍历:第一个节点的数据乘1加到sum,第二个节点的数据乘2加到sum,第三个节点的数据乘3加到sum……;然后再反向进行第二次遍历,sum减去最后一个节点的数据和1的乘积,sum减去倒数第二个节点的数据和2的乘积……。只要看最后的sum是否为0就可以判断链表是否回文。当然,在第一次遍历的时候需要一边遍历一边逆置该链表,才能进行第二次遍历。贴上代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head)
{
ListNode *point1, *point2, *point3;
point3 = point2 = head;
point1 = NULL;
long int sum = ;
int n = ;
if(head == NULL || head->next == NULL
return true;
while(point3->next != NULL)//第一次遍历,取值并逆置
{
sum += n*point3->val;
n++;
point3 = point3->next;
point2->next = point1;
point1 = point2;
point2 = point3;
}
sum += n*point3->val;
point2->next = point1;
n = ;
while(point2 != NULL)//第二次遍历
{
sum -= n*point2->val;
n++;
point2 = point2->next;
}
if(sum == )
return true;
else
return false;
}
};
提交的结果显示这个方法在题目的条件范围内是可行的:

仔细一想,如果节点中的数据是字符,是浮点数怎么办?这时这个方法的局限性就显现出来了。
3,不能用一个整型来存储字符这类的信息,那只能直接比较节点里的信息了。怎么比较?我们知道回文链表的特点就是对称,那么要判断是否回文就可以用两个指针指向对称的节点,看里面的信息是否一样。即对称的位置是否有对称的信息。由于是单向链表,不能同时用两个指针从头尾向内部遍历取值比较。那么就考虑从链表中间开始,用两个指针向两头遍历取值比较,显然这也需要进行链表逆置。
具体的做法就是先遍历一次链表得到链表长度。然后第二次遍历到链表中间,并在遍历的时候进行逆置。然后两个指针分离,分别向两个端点移动,同时进行比较,数据相同则继续,数据不同则直接返回false。直到遍历完成,最后返回true。代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head)
{
int lenth, i;
ListNode *point1, *point2, *point3;
point3 = point2 = head;
point1 = NULL;
lenth = ;
if(head == NULL || head->next == NULL)
return true;
while(point3 != NULL)//取得长度
{
point3 = point3->next;
lenth++;
}
for(i = ;i < (lenth / );i++)//遍历到中间,并逆置
{
point3 = point2->next;
point2->next = point1;
point1 = point2;
point2 = point3;
}
if((lenth % ) == )
point3 = point3->next;
while(point3 != NULL && point1 != NULL)//两个指针开始向两头移动,取值比较
{
if(point3->val != point1->val)
return false;
point3 = point3->next;
point1 = point1->next;
}
return true;//比较中没有发现不同值,则为回文链表
}
};
最后的结果也证明这个方法是可行的:

比起上一种方法,这个方法没有存储信息的操作,所以不必担心用什么数据类型去存储,也不用担心数据的溢出,适用的范围当然也就更大。
若博文中有什么不正确的地方欢迎大家指正,谢谢~
如何判断一个单向链表是否为回文链表(Palindrome Linked List)的更多相关文章
- Java判断链表是否为回文链表
请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 思路:1.通过快慢指针,来遍历链表 ...
- LeetCode OJ:Palindrome Linked List(回文链表判断)
Given a singly linked list, determine if it is a palindrome. Follow up:Could you do it in O(n) time ...
- Leetcode 234. 回文链表(进阶)
1.题目描述 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O ...
- [LeetCode] Palindrome Linked List 回文链表
Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) time ...
- [Swift]LeetCode234. 回文链表 | Palindrome Linked List
Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false ...
- Leetcode:234 回文链表
leetcode:234 回文链表 关键点:请判断一个链表是否为回文链表.示例 1:输入: 1->2输出: false示例 2:输入: 1->2->2->1输出: true. ...
- 【leetcode 简单】 第六十七题 回文链表
请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复 ...
- 回文链表 · Palindrome Linked List
[抄题]: 设计一种方式检查一个链表是否为回文链表.1->2->1 就是一个回文链表. [暴力解法]: 时间分析: 空间分析: [思维问题]: 以为要从从后往前扫描,不知道调用revers ...
- LeetCode 234——回文链表
1. 题目 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O( ...
随机推荐
- iview的table中点击Icon弹Poptip,render函数的写法
render: (h, params) => { return h('div', [ h('div', [ h('Poptip', { props: { confirm: true, trans ...
- Git在Eclipse中的使用
一.把远程仓库的项目clone到eclipse里面: 最新版的Eclipse上已经集成了Git插件.所以在Eclipse中可以很方便的使用Git的功能. 在使用Git功能之前,需要先进行下简单的设置. ...
- [转载]ViewPort <meta>标记
ViewPort <meta>标记用于指定用户是否可以缩放Web页面,如果可以,那么缩放到的最大和最小缩放比例是什么.使用 ViewPort <meta>标记还表示文档针对移动 ...
- Hadoop学习笔记之一:Hadoop IPC
因为某些原因需要把前一段时间对Hadoop(版本基于0.20.2)的学习积累搬到这里,成为一个系列.写得会很简单,只为必要时给自己提醒. IPC框架 所有Hadoop协议接口的实现都依赖Hadoop ...
- Django基础(10): URL重定向的HttpResponseDirect, redirect和reverse的用法详解
利用django开发web应用, 我们经常需要进行URL重定向,有时候还需要给URL传递额外的参数.比如用户添加文章完成后需要转到文章列表或某篇文章详情.因此熟练掌握HttpResponseDirec ...
- PHP API接口签名验证
hash_hmac 在php中hash_hmac函数就能将HMAC和一部分哈希加密算法相结合起来实现HMAC-SHA1 HMAC-SHA256 HMAC-MD5等等算法.函数介绍如下: string ...
- django创建app、在视图函数及url中使用参数、url命名、通过redirect实现网页路径跳转
app用来实现一个独立的功能,视图一般都写在app的view.py中,并且视图的第一个参数永远是request,视图的返回值必须是HttpResponseBase对象或子类的对象. 创建一个app:f ...
- Markdown语法学习(Github/git.oschina.net上README.md书写规范)(转)
晚上在更新git.oschina.net项目时,突然想知道README.md后缀的来源,于是搜了下,发现README.md使用了一种小标记语言Markdown的语法,于是简单的看了一个,特转载如下,为 ...
- python之字符编码(三)
一.字符编码的分类: 计算机由美国人发明,最早的字符编码为ASCII,只规定了英文字母数字和一些特殊字符与数字的对应关系.最多只能用 8 位来表示(一个字节),即:2**8 = 256,所以,ASCI ...
- 【题解】Luogu P5072 [Ynoi2015]盼君勿忘
众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题 我博客里对莫队的简单介绍 既然是莫队,我们就要考虑每多一个数或少一个数对答案的贡献是什么 假 ...