234. 回文链表
题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
思路
快慢指针的解法,快指针比慢指针快2倍,设快指针能够进行的完整的操作时,慢指针走过的路径为x,则此时快指针已经走过的路径为2x,整个链表的路径为l,则:l = 2x+r(r=0或1)终止操作时,慢指针指向的节点所在的前半部分链表的节点数为:x+1(节点数为路径+1)此时,后半部分链表的节点数为:x+r(慢指针所指节点分给了前半部分)当r=0时,前后节点数为:x+1,x,此时慢指针所指节点的下一个节点可以作为二分链表的开始位置, x,1(这个节点不影响回文判断),x
当r=1时,前后节点数为:x+1,x+1,此时慢指针所指节点的下一个节点同样可以作为二分链表的开始位置,x+1,x+1
代码实现
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head == nullptr || head->next == nullptr)
return true;
ListNode *fast=head;
ListNode *slow=head;
//循环条件为针对快指针的操作还能不能继续进行?
while(fast->next && fast->next->next)
{
slow = slow->next;
fast = fast->next->next;
}
fast = slow->next;
slow->next = nullptr;
slow = head;
fast = reverseList(fast);
while(fast!=nullptr)
{
if(fast->val != slow->val)
return false;
fast = fast->next;
slow = slow->next;
}
return true;
}
ListNode* reverseList(ListNode* head) {
if(head==nullptr || head->next==nullptr)
return head;
ListNode *last = nullptr;//尾指针的方法
ListNode *cur = head;
while(cur!=nullptr)
{
ListNode * temp = cur->next;
cur->next = last;
last = cur;
cur = temp;
}
return last;
}
};