思路:
反转前半段链表,再跟后半段链表作比较
代码来源:
https://blog.csdn.net/azulgrana02/article/details/112490515
//前半部分反转链表,再比较
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode* q = head; //快指针
ListNode* cur = head, * pre = NULL; //反转链表的模板
while(q && q->next) {
q = q->next->next; //2倍慢指针的速度
ListNode* temp = cur->next; //反转链表的模板
cur->next = pre;
pre = cur;
cur = temp;
}
if(q) cur = cur->next; //奇数链表处理,跳过中间节点
while(pre) { //开始对比
if(pre->val != cur->val) return false;
pre = pre->next;
cur = cur->next;
}
return true;
}
};
也可以反转后半部分链表再比较,这个代码我在写的时候在比较的部分用cur指针去判断是否执行循环,但当上一个循环结束时cur其实已经指向nullptr了,比较部分的循环代码一直无法进入,程序永远返回true。因此,我们应当用pre指针来做判断条件。
//反转后半部分链表再比较
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode* cur=head;
ListNode* fast=head;
ListNode* A=head;
ListNode* pre=nullptr;
ListNode* next;
while(fast && fast->next)
{
cur=cur->next;
fast=fast->next->next;
}
if(fast)
{cur=cur->next;}//奇数链表处理,跳过中间节点
while(cur)
{
next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
fast=head;
//此时cur已经指空,pre才是指向反转链表的头结点的指针
while(pre)
{
if(fast->val != pre->val)
{
return false;
}else
{
fast=fast->next;
pre=pre->next;
}
}
return true;
}
};
此外,我还写了另外一种方法,这种方法能实现回文链表功能,但是耗时比前两种要救久,留给大家参考参考。这种方法无需反转链表即可实现判断回文链表
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode* cur_a=head;
ListNode* temp;
ListNode* BackHead=head;
int length=0;
int BackLength=0;
//求链表长度
while(BackHead)
{
BackHead=BackHead->next;
length++;
}
BackLength=length;
BackHead=head;
for(int i=0;i<length/2;i++)
{
for(int j=0;j<BackLength-1;j++)
{
BackHead=BackHead->next;
}
if(cur_a->val!=BackHead->val)
{
return false;
}
BackHead=head;
cur_a=cur_a->next;
BackLength--;
}
return true;
}
};