Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
判断链表是否是回文,第一想法是遍历一次通过相加的方式得到sum,然后同时逆置链表,之后再相加得到temp,看是否相等。
代码如下:
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head==NULL||head->next==NULL)
return true;
ListNode* p=head;
int sum=0;
int i=1;
ListNode* q=p->next;
ListNode* t=NULL;
while(q!=NULL)
{
sum+=p->val*i;
i++;
p->next=t;
t=p;
p=q;
q=p->next;
}
sum!=p->val*i;
p->next=t;
int j=1;
int temp=0;
while(p!=NULL)
{
temp+=p->val*j;
j++;
}
if(temp==sum)
return true;
else
return false;
}
};
但是时间超时了,因为遍历了两次,On只允许遍历一次。
这时候想到了能不能试着找到链表中间节点,百度了一圈学会了可以用快慢指针的方法。
快指针每次走两个节点,慢指针每次走一个。等到快指针的next和next->next有一个为NULL时,慢节点就到了链表的中间节点。是个非常好的方法应该学会。
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head==NULL||head->next==NULL)
return true;
ListNode* fast=head;
ListNode* slow=head;
while(fast->next!=NULL&&fast->next->next!=NULL)
{
fast=fast->next->next;
slow=slow->next;
}
ListNode* p=slow->next;
ListNode* q=p->next;
ListNode* t=NULL;
ListNode* pre=head;
while(q!=NULL)
{
p->next=t;
t=p;
p=q;
q=q->next;
}
p->next=t;
slow->next=p;
while(p!=NULL)
{
if(pre->val!=p->val)
return false;
pre=pre->next;
p=p->next;
}
return true;
}
};