题目描述:
给定一个链表的头节点,请判断其是否为回文链表。
回文链表:链表节点序列从前往后看和从后往前看是相同的。
设计思想:
首先通过龟兔赛跑法把链表节点分成两段,返回第一个链表的末尾节点。龟兔赛跑法是指用一个fast指针代表兔子,slow指针代表乌龟。每次循环兔子往后走两步,乌龟往后走一步,直到兔子节点的next或next的next为空指针时,返回slow。
然后通过返回的slow->next,进行对原始链表后半部分进行反转,返回后半部分反转后的链表的头节点。
最后使前半部分的头节点和后半部分的头节点对齐,一一进行比较,直到p1->val!=p2->val,返回false,否则返回true。(如果链表首先就是nullptr,那么直接返回true)。
实现代码如下:
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head==nullptr){
return true;
}
ListNode *endoffirstHalf=endoffirstlist(head);
ListNode *startoffirstHalf=reverelist(endoffirstHalf->next);
ListNode *p1=head;
ListNode *p2=startoffirstHalf;
while(p2!=nullptr){
if(p1->val!=p2->val){
return false;
}
p1=p1->next;
p2=p2->next;
}
return true;
}
ListNode* endoffirstlist(ListNode* head){
ListNode *fast=head;
ListNode *slow=head;
while(fast->next!=nullptr&& fast->next->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
ListNode* reverelist(ListNode* head){
ListNode *cur=head;ListNode *pre=nullptr;
while(cur!=nullptr){
ListNode *tmp=cur->next;
cur->next=pre;
pre=cur;
cur=tmp;
}
return pre;
}
};