快慢指针+反转链表
具体要求是时间复杂度是O(N),空间复杂度是O(1)
先找到链表的中点 : 这个很简单,快慢指针就可以办到了,slow = slow->next; fast = fast->next->next;
一次遍历之后,slow所指即为链表中点
然后对 slow之后的节点进行反转,不需要区分奇偶的,这里用图简单说明一下:
作者:zuo-10
链接:https://leetcode-cn.com/problems/palindrome-linked-list/solution/c-shi-yong-shu-zu-fan-zhuan-lian-biao-by-zuo-10/
/**
* 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) {
// 方法1. 使用数组
/*
vector<int> v;
while(head){
v.push_back(head->val);
head = head->next;
}
// 判断是否回文
for(int i=0; i<v.size()/2; ++i){
if(v[i] != v[v.size()-1-i]){
return false;
}
}
return true;
*/
// 方法2. 反转链表
if(!head || !head->next) return true;
ListNode* slow = head, * fast = head;
// 将slow指针移动到链表中间位置
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
}
// 反转后半部分
ListNode* curNode = slow, *nextNode = slow->next;
while(nextNode){
ListNode* tmp = nextNode->next;
nextNode->next = curNode;
curNode = nextNode;
nextNode = tmp;
}
slow->next = nullptr;
// 开始比较是否相等
while(head && curNode){
if(head->val != curNode->val)
return false;
head = head->next;
curNode = curNode->next;
}
return true;
}
};