1.快慢指针
找中点(注意奇偶)
分开
反转后半链
比较(以后半链为主)
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode *p=new ListNode(-1);//预先指针
ListNode *fast=p;
ListNode *low=p;
p->next=head;
while(fast&&fast->next)//找中点
{
low=low->next;
fast=fast->next->next;
}
ListNode *cur=low->next;//后半链当前指针
ListNode *pre=NULL;//用于反转 摘掉结点 头插法
low->next=NULL;//断链
low=head;//重置low
//反转
while(cur)//注意结束条件
{ //cur一开始在后半链第一个
ListNode *temp;
temp=cur->next;//后链第一个结点的后一个,有助于结束 备份cur->next
cur->next=pre;//将后半链第一个结点摘掉
pre=cur;//反转 再次循环使下一个结点指向当前结点
cur=temp;//操作了cur->next 需要备份temp 有助于结束 相当于把原来的cur向后移一位
}
//比较判断
while(pre)//此时pre在后半链第一个
{
if(low->val!=pre->val)//不等直接输出false 注意此处不可相等则返回true
return false;
low=low->next;
pre=pre->next;
}
return true;
}
};
2.利用动态数组(向量)
将节点的值存入向量中,从两端开始遍历,不等则false
代码:
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head||!head->next) return true;//注意此处
vector<int> List;
while(head)
{
List.push_back(head->val);
head=head->next;
}
int i=0;
int j=List.size()-1;
while(i<j)
{
if(List[i]!=List[j])
return false;
i++;
j--;
}
return true;
}
};
两种方法效率对比: