Palindrome Linked List
234-palindrome-linked-list
Date created: 2025-05-03-Sat 18:39
Question Description
Given the head of a singly linked list, return true if it is a
or false otherwise.
Example 1:
Input: head = [1,2,2,1] Output: true
Example 2:
Input: head = [1,2] Output: false
Constraints:
The number of nodes in the list is in the range [1, 105].
0 <= Node.val <= 9
Follow up: Could you do it in O(n) time and O(1) space? Seen this question in a real interview before?
Thought Process
- Don’t be fooled by the easy tag, this is at least medium considering the amount of code and thought process!
-
everytime when I see a reverse problem, and it’s involing linked-list, I’ll imediately thinking about fast slow potiner
-
we use the fast slow potiner to find the mid
-
then we reverse the second half of the linked list
# 1 -> 2 -> 3
# prev cur
#------------------------
# <- 1 2 -> 3
# prev cur next
#------------------------
# <- 1 <- 2 -> 3
# prev cur next
key code snippet:
# change direction of the pointer
next_node = cur.next
cur.next = prev
# go to next node, do the same thing
prev = cur
cur = next_node
Code
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
"""Fast slow ptr.
slow will eventually goes to mid fast will point to end and we
have start ptr so we then can compare start and fast ptr just
like what we did for regular list mid will be at slow ptr
"""
fast, slow = head, head
while fast and fast.next:
fast = fast.next
fast = fast.next
slow = slow.next
# we can reverse the 2nd half of the list , if it's palindrome, 2nd half will be like 1st half if reversed
cur, prev = slow, None
# reverse
while cur:
# fmt: off
# 1 -> 2 -> 3
# prev cur
#------------------------
# <- 1 2 -> 3
# prev cur next
#------------------------
# <- 1 <- 2 -> 3
# prev cur next
# fmt: on
next_node = cur.next
cur.next = prev
prev = cur
cur = next_node
# print("===second half list after reversing the 2nd half===")
# print_list(prev) # prev is now the head of the reversed second half
# print("===second half list after reversing the 2nd half===")
#
# now the second half is exactly same as first half(if it's palindrome)
ptr = head
while prev:
if ptr.val != prev.val:
return False
ptr = ptr.next
prev = prev.next
# the reversed second half has same values as the first half
return True
Time/Space Complexity
-
Time: \( O(n) \) since \( O(n) \) to find the mid + \( O(n) \) to use two-pointer technique to reverse the second-half of the linked list
-
Space: \( O(1) \) since we are not using any extra space, just pointers