描述
给定一个链表,请判断该链表是否为回文结构。
回文是指该字符串正序逆序完全一致。
数据范围: 链表节点数 0 \le n \le 10^70≤n≤107,链表中每个节点的值满足 |val| \le 10^7∣val∣≤107.
普通字符串回文因为可以直接获得长度,直接利用双指针,一个从头往尾,一个从尾往前,很好解决。
因为是单向链表,不能从后往前遍历,所以我们得想办法让其中一个指针从后往前。
很容易想到反转链表,但是反转链表是整个反转,显然不能解决问题。
从题目出发,回文是从前往中间和从后往中间的字符完全一样,那么我们怎么找到这个中间呢,
利用快慢指针,慢指针每次只走一步,而快指针每次走两步,当快指针指向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;
}
};

京公网安备 11010502036488号