方法一:
遍历链表,将元素放入数组中,然后使用双指针判断
时间复杂度:O(n)
空间复杂度:O(n)
方法二:递归
递归,使得尾指针先到达链表尾部,然后依靠其返回顺序与头指针比较,相当于实现了尾指针从后向前与从前向后的头指针比较。
时间复杂度O(n)
空间复杂度O(n)
class Solution {
public:
ListNode*front;
bool rcheck(ListNode*current){
if(current){
if(!rcheck(current->next))//若前一个节点不匹配,直接false一路返回
return false;
if(front->val!=current->val)//前一节点匹配,若本节点不匹配,直接false一路返回
return false;
front=front->next;//本节点匹配,进行下一节点的匹配
}
return true;//到达链表末尾(或本节点匹配)返回ture开始比较
}
bool isPalindrome(ListNode* head) {
front=head;
return rcheck(head);
}
};
方法三:反转链表
这里使用了快慢指针,慢指针走一步,快指针走两步,快的先走,若快指针未到nullptr慢指针再走,当快指针到nullptr,此时慢指针在前半部分最后一个(链表元素为偶数)或者正好在中间(链表元素为奇数)
时间复杂度O(n)
空间复杂度O(1)
class Solution {
public:
ListNode*reverseList(ListNode*cur){//反转链表
ListNode*prev=nullptr;
while(cur){
ListNode*tem=cur->next;
cur->next=prev;
prev=cur;
cur=tem;
}
return prev;
}
ListNode*endOfFirstPart(ListNode*head){//寻找第一部分最后的元素
ListNode*fast=head;
ListNode*slow=head;
while(fast->next&&fast->next->next){
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
bool isPalindrome(ListNode* head) {
ListNode*endOfFirst=endOfFirstPart(head);
ListNode*re=reverseList(endOfFirst->next);
bool result=true;
ListNode*current=head,*rev=re;
while(result&&re){//前半部分长度大于等于后半部分长度
if(current->val!=re->val)
result=false;
current=current->next;
re=re->next;
}
reverseList(rev);
return result;
}
};