# Solution 2
def isPalindrome(head: Optional[ListNode]) -> bool:
revert_half = None # revert_half that will contains the reversed first half
fast, slow = head, head # fast will advance two by two and slow head will be set to the middle element
# both fast and fast.next need to exist to advance by two
while fast and fast.next:
fast = fast.next.next # advance two by two
# revert_half.next will take the value of revert_half and revert_half becomes slow
revert_half, revert_half.next, slow = slow, revert_half, slow.next
# adjust the middle
if fast:
slow = slow.next
# check if reversed first half and second half are equivalent
while slow:
# if not equivalent for a node returns False
if slow.val != revert_half.val:
return(False)
revert_half, slow = revert_half.next, slow.next
# Otherwise returns True
return(True)