234. Palindrome Linked List - cocoder39/coco39_LC GitHub Wiki
main idea is not difficult:
- 
- divide the list into two halves A and B
 
 - 
- reverse B
 
 - 
- check if A == B
 
 
however, too many implementation details:
- how to divide the list into 2 halves?
 
quick answer is using fast and slow pointers, problem is using while (fast->next && fast->next->next) or while (fast && fast->next). we should handle both even elements and odd elements.
Here both fast and slow start from 1st element, supposing there are 2n+1 (which is 1 + 2n) / 2n+2 (which is 1 + 2n+1) elements in total.
In case while (fast->next && fast->next->next), fast would stop at the last element instead of nullptr. Consequently, slow would stops at 1 + n. Hence, slow->next would be the head of second half head2 no matter there are 2n+1/2n+2 elements.
- why 
if (! head) 
precondition of while (fast->next && fast->next->next) is fast != nullptr
slow->next = reverseList(slow->next)to link the reversed second half to first half
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if (! head) {
            return true;
        }
        
        ListNode* fast = head;
        ListNode* slow = head;
        //suppose there are 2n+1/2n+2 elements in total
        //fast and slow start from 1st element
        //fast stops at 2n+1/2n+2
        //slow stops at n+1
        //in either case slow->next is head of second half
        while (fast->next && fast->next->next) { //vs while (fast && fast->next), fast stops at last element instead of nullptr
            slow = slow->next;
            fast = fast->next->next;
        }
        
        slow->next = reverseList(slow->next);
        ListNode* head2 = slow->next; 
        
        while (head2) {
            if (head->val != head2->val) {
                slow->next = reverseList(slow->next);
                return false;
            }
            head = head->next;
            head2 = head2->next;
        }
        slow->next = reverseList(slow->next);
        return true;
    }
private:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* nxt = head;
        while (nxt) {
            ListNode* cur = nxt;
            nxt = nxt->next;
            cur->next = pre;
            pre = cur;
        }
        return pre;
    }
};