描述

给定一个链表,请判断该链表是否为回文结构。
回文是指该字符串正序逆序完全一致。
数据范围: 链表节点数 0 \le n \le 10^70n107,链表中每个节点的值满足 |val| \le 10^7val107.

普通字符串回文因为可以直接获得长度,直接利用双指针,一个从头往尾,一个从尾往前,很好解决。
因为是单向链表,不能从后往前遍历,所以我们得想办法让其中一个指针从后往前。
很容易想到反转链表,但是反转链表是整个反转,显然不能解决问题。
从题目出发,回文是从前往中间和从后往中间的字符完全一样,那么我们怎么找到这个中间呢,
利用快慢指针,慢指针每次只走一步,而快指针每次走两步,当快指针指向null,或者快指针的下一个指向null时,
slow->next就是我们需要反转的开始,让fast指向slow->next,并且从fast开始反转链表。
反转结束会后,让慢指针重新指向头节点。
接着逐个比较快慢指针(此时快指针每次也只走一步)的值,遇到值不同时,说明不是回文,返回false。
如果一直比较到快指针到null还没有返回false,说明已经比较完且每个值都相同,返回true。
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    bool isPail(ListNode* head) {
        // write code here
        if(head==NULL||head->next==NULL) return true;
        ListNode *slow,*fast;
        slow=head,fast=head->next;
        while(fast->next!=NULL&&fast!=NULL) slow=slow->next,fast=fast->next->next;
        fast=slow->next,slow=head;
        fast=ReveseList(fast);
        while(fast!=NULL) {
            if(slow->val!=fast->val) return false;
            slow=slow->next;
            fast=fast->next;
        }
        return true;
    }
public: ListNode* ReveseList(ListNode* Head) {
        ListNode* p=NULL;
        ListNode* q=NULL;
        while(Head!=NULL)
        {
            q=Head;
            Head=Head->next;
            q->next=p;
            p=q;
        }
        return p;
    }
};