1.题目
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2 输出: false示例 2:
输入: 1->2->2->1 输出: true
2.code
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode *pre,*pcur,*phead,*p;
p=head;
int n=0;
while(p!=NULL)
{
p=p->next;
n+=1;
}
if(n==1||n==0)
return true;
if(n%2==0)
{
int flag=0;
phead=new ListNode(-1);
phead->next=head;
pre=phead->next;
pcur=pre->next;
int cnt=1;
while(cnt<n/2)
{
pre->next=pcur->next;
pcur->next=phead->next;
phead->next=pcur;
pcur=pre->next;
cnt++;
}
while(phead->next!=NULL&&pcur!=NULL)
{
if(phead->next->val!=pcur->val)
{
flag=1;break;
}
phead=phead->next;
pcur=pcur->next;
}
if(flag==1)
return false;
else
return true;
}
else
{
int flag=0;
phead=new ListNode(-1);
phead->next=head;
pre=phead->next;
pcur=pre->next;
int cnt=1;
while(cnt<=n/2)
{
pre->next=pcur->next;
pcur->next=phead->next;
phead->next=pcur;
pcur=pre->next;
cnt++;
}
phead=phead->next;
while(phead->next!=NULL&&pcur!=NULL)
{
if(phead->next->val!=pcur->val)
{
flag=1;break;
}
phead=phead->next;
pcur=pcur->next;
}
if(flag==1)
return false;
else
return true;
}
}
};
3.思路
首先求链表长度,得知链表长度的时候分两种情况:长度为奇数;长度为偶数。(1)长度为奇数,则中间有一个数,两头完全对称。(2)长度为偶数,中间没有多余的数,两头完全对称。
其次,我们的思路是反转一半链表,如果是个回文链表的话,那么经过反转的这一半和剩下的这一半是完全相等的。当然如果是奇数的情况,开头会多一个数。我们只需要分别遍历这两部分链表,看是否会相等。如果全部相等,那么回文,否则no.
在反转链表的时候,我们选择原地反转,但是需要额外申请一个头节点,原来的链表没有头节点,当我们直接赋值pre=phead=head,进行操作会发生错误,进入死循环。