思路:
(1)找到链表的中间位置,如果是结点为偶数,那么前一半和后一半长度一样,中间位置指针要落在前一半的末尾,奇数节点不影响必然落在中间。
(2)反转后面一部分的链表,中间切断。
(3)比较两个子链表的每一个结点的值,如果是回文,那么后一半的指针指向空的时候则结束(因为前一个链表长度一定是>=后一个的)。
时间复杂度o(n),空间复杂度o(1)。
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head->next == nullptr)
{
return true;
}
ListNode* mid = findmid(head);
ListNode* next = mid->next;
mid->next = nullptr;
ListNode* newHead = reverseList(next);
ListNode* fast = head;
ListNode* slow = newHead;
while (fast->val == slow->val)
{
fast = fast->next;
slow = slow->next;
if(slow==nullptr)
return true;
}
return false;
}
ListNode* findmid(ListNode* head)
{
ListNode* fast = head;
ListNode* slow = head;
while (fast->next != nullptr && fast != nullptr)
{
fast = fast->next;
if (fast->next == nullptr)
return slow;
slow = slow->next;
if (fast->next != nullptr)
fast = fast->next;
}
return slow;
}
ListNode* reverseList(ListNode* head) {
if (!head || !head->next) {
return head;
}
ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
};