问题描述
给定一个链表,判断是否为回文链表
如: 1->2,false
1->2->2->1,true
【解法一】常规解法
遍历链表,把每个节点的值储存在数组中,然后判断该数组是否回文
时间复杂度O(n),空间复杂度O(n)
C++代码如下:
bool isPalindrome(ListNode* head) {
if(head==NULL) return true;
vector<int> a;
int count=0,n;
ListNode* p;
p=head;
while(p!=NULL)
{
a.push_back(p->val);
p=p->next;
}
n=a.size();
for(int i=0;i<n/2;i++)
{
if(a[i]!=a[n-1-i]) return false;
}
return true;
}
【解法二】 快慢指针+链表反转+比较
时间复杂度O(n),空间复杂度O(1)
1.首先使用快慢指针找到中间节点(具体用法见上一节),如果节点个数为奇数,中间节点往后移一位
2.将中间节点及以后的部分反转(cur=slow)
3.至此,后半部分反转完成
4.然后前后两部份分别从各自头节点(head,cur)开始逐点往后比较,直到后半部分到达结尾,如果对应的值都相等则为回文链表,反之只要有一点不等则不是
C++代码如下:
bool isPalindrome(ListNode* head) {
if(head==NULL||head->next==NULL) return true;
ListNode* slow,*fast;
slow=fast=head;
while(fast!=NULL||fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
}
if(fast!=NULL) slow=slow->next;
ListNode*cur,*temp,*pre;
cur=pre=slow;
temp=cur->next;
pre->next=NULL;
while(temp!=NULL)
{
cur=temp;
temp=temp->next;
cur->next=pre;
pre=cur;
}
while(cur!=NULL)
{
if(cur->val!=head->val) return false;
cur=cur->next;
head=head->next;
}
return true;
}
好了,就写到这啦!