方法一:辅助数组
将链表的节点值存在数组里,判断是否回文
方法二: 双指针+反转链表
1. 使用双指针找到链表的中间节点
2. 从中间节点进行反转链表(对链表进行头插法)
两种方法的代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
// 要求时间:o(n),空间o(1)
// 方法一:辅助数组
// bool isPalindrome(ListNode* head) {
// vector<int> p;
// while(head){
// p.push_back(head->val);
// head=head->next;
// }
// int len = p.size();
// int right=0;
// int left = 0;
// // 检查回文
// if(len%2==0){
// left = len/2-1;
// right = len/2;
// }else{
// left = len/2-1;
// right = len/2+1;
// }
// while(left>=0&&right<len){
// cout<<p[left]<<" "<<p[right]<<endl;
// if(p[left--]!=p[right++]){
// return false;
// }
// }
// return true;
// }
// 方法二: 双指针+逆转链表
bool isPalindrome(ListNode* head){
ListNode* q = head;
ListNode* s = head;
while(q){
s = s->next;
q = q->next;
if(q!=nullptr){
q = q->next;
}
}
// 此时s指向半段的一个节点
// 反转链表
ListNode* new_head = new ListNode();;
new_head->next = nullptr;
// 头插法
while(s){
ListNode* p = s->next;
s->next = new_head->next;
new_head->next = s;
s = p;
}
ListNode* p = new_head->next;
// 比较
while(head&&p){
if(head->val != p->val){
return false;
}
head = head->next;
p = p->next;
}
return true;
}
};