Palindrome Linked List
franklinqin0 Math
# Definition for Singly-Linked List
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
1
2
3
4
2
3
4
# Solution
All solutions below take linear time.
# Linear Space
# Two Pointers
def isPalindrome(self, head: Optional[ListNode]) -> bool:
stk = []
p = head
while p is not None:
stk.append(p)
p = p.next
p = head
while len(stk) > 0 and stk.pop().val == p.val:
p = p.next
return len(stk) == 0
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Recursion
def isPalindrome(self, head: ListNode) -> bool:
self.front = head
def check(curr=head):
if curr:
if not check(curr.next):
return False
if curr.val != self.front.val:
return False
self.front = self.front.next
return True
return check()
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# Follow Up
Could you do it in time and space?
# Constant Space
# Fast and Slow Pointers
- use 2 pointers (fast & slow), find middle pointer
- reverse latter part of linked list
- compare 2 pointers to check if palindrome
def isPalindrome(self, head: Optional[ListNode]) -> bool:
slow = fast = head
while fast is not None and fast.next is not None:
slow = slow.next
fast = fast.next.next
p2 = self.reverseLinkedList(slow)
p1 = head
while p2 is not None:
if p1.val != p2.val:
return False
p1 = p1.next
p2 = p2.next
return True
def reverseLinkedList(self, head):
prev = None
curr = head
while curr is not None:
nxt = curr.next
curr.next = prev
prev = curr
curr = nxt
return prev
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24