is_palindrome.py
def is_palindrome(head):⏎
if not head:⏎
return True⏎
# split the list to two parts⏎
fast, slow = head.next, head⏎
while fast and fast.next:⏎
fast = fast.next.next⏎
slow = slow.next⏎
second = slow.next⏎
slow.next = None # Don't forget here! But forget still works!⏎
# reverse the second part⏎
node = None⏎
while second:⏎
nxt = second.next⏎
second.next = node⏎
node = second⏎
second = nxt⏎
# compare two parts⏎
# second part has the same or one less node⏎
while node:⏎
if node.val != head.val:⏎
return False⏎
node = node.next⏎
head = head.next⏎
return True⏎
⏎
⏎
def is_palindrome_stack(head):⏎
if not head or not head.next:⏎
return True⏎
⏎
# 1. Get the midpoint (slow)⏎
slow = fast = cur = head⏎
while fast and fast.next:⏎
fast, slow = fast.next.next, slow.next⏎
⏎
# 2. Push the second half into the stack⏎
stack = [slow.val]⏎
while slow.next:⏎
slow = slow.next⏎
stack.append(slow.val)⏎
⏎
# 3. Comparison⏎
while stack:⏎
if stack.pop() != cur.val:⏎
return False⏎
cur = cur.next⏎
⏎
return True⏎
⏎
⏎
def is_palindrome_dict(head):⏎
if not head or not head.next:⏎
return True⏎
d = {}⏎
pos = 0⏎
while head:⏎
if head.val in d.keys():⏎
d[head.val].append(pos)⏎
else:⏎
d[head.val] = [pos]⏎
head = head.next⏎
pos += 1⏎
checksum = pos - 1⏎
middle = 0⏎
for v in d.values():⏎
if len(v) % 2 != 0:⏎
middle += 1⏎
else:⏎
step = 0⏎
for i in range(0, len(v)):⏎
if v[i] + v[len(v) - 1 - step] != checksum:⏎
return False⏎
step += 1⏎
if middle > 1:⏎
return False⏎
return True⏎