Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
Let's analyse it a bit. the length of the linked list has two case: odd and even: 1->2->3; 1->2->3->4
We use a slow pointer and a fast pointer. Slow one moves one node each step, fast one moves two node each.
Thus, we can get the middle when there is no fast->next && fast->next->next; To check palindrome, we just need to reverse the second part and compare it with the first part until one of the list reach null.
ListNode* reverse(ListNode* tmp) {
if(!tmp || !tmp->next) return tmp;
ListNode* dummy = NULL;
ListNode* head = tmp;
while(head) {
ListNode* next = head->next;
head->next = dummy;
dummy = head;
head = next;
}
return dummy;
}
bool isPalindrome(ListNode* head) {
if(!head || !head->next) return true;
// reverse second part.
ListNode* fast = head;
ListNode* slow = head;
while(fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* reHead = slow->next;
slow->next = NULL; // remember to set slow->next to NULL.
ListNode* tmp = reverse(reHead);
while(head && tmp) { // if it is odd, when the short length is done, the whole compare is done..
if(head->val != tmp->val) return false;
head = head->next;
tmp = tmp->next;
}
return true;
}