Linked List Palindrome
Linked List Palindrome
Category
Linked Lists
Difficulty
Hard
Problem Statement
Given the head of a singly linked list, determine whether the linked list is a palindrome. A linked list is a palindrome if the sequence of values reads the same forwards and backwards. The algorithm should ideally use O(1) extra space.
Intuition
To check if a linked list is a palindrome in O(1) space, we can reverse the second half of the list and then compare it with the first half. We find the midpoint using the slow/fast pointer technique, reverse the second half in place, compare the two halves node by node, and optionally restore the list to its original state.
Approach
- Use a slow pointer (moves 1 step) and a fast pointer (moves 2 steps) to find the middle of the list.
- When the fast pointer reaches the end, the slow pointer is at the midpoint.
- Reverse the second half of the linked list starting from the slow pointer.
- Compare the first half (from head) and the reversed second half node by node.
- If all corresponding values match, the list is a palindrome.
- Optionally, reverse the second half again to restore the original list structure.
Pseudocode
function linkedListPalindrome(head):
if head is null or head.next is null:
return true
// Find middle
slow = head
fast = head
while fast is not null and fast.next is not null:
slow = slow.next
fast = fast.next.next
// Reverse second half
secondHalfHead = reverseList(slow)
// Compare halves
firstHalf = head
secondHalf = secondHalfHead
while secondHalf is not null:
if firstHalf.value != secondHalf.value:
// Optionally restore: reverseList(secondHalfHead)
return false
firstHalf = firstHalf.next
secondHalf = secondHalf.next
// Optionally restore: reverseList(secondHalfHead)
return true
function reverseList(head):
prev = null
current = head
while current is not null:
nextNode = current.next
current.next = prev
prev = current
current = nextNode
return prev
Time & Space Complexity
- Time: O(n) where n is the number of nodes. Finding the middle takes O(n/2), reversing takes O(n/2), and comparison takes O(n/2).
- Space: O(1) extra space. The list is modified in place; no additional data structures are used.
Key Insights
- The slow/fast pointer technique reliably finds the midpoint in a single pass.
- For odd-length lists, the middle node is shared and does not affect the palindrome comparison since it matches with itself.
- Reversing only the second half avoids the need for a stack or array, achieving O(1) space.
- Restoring the list after checking is good practice, especially if the list is used elsewhere.
- An alternative O(n) space approach uses a stack: push all values, then traverse again comparing with popped values.
Edge Cases
- Empty list — considered a palindrome (vacuously true).
- Single node — always a palindrome.
- Two nodes — palindrome only if both values are equal.
- Even-length palindrome (e.g., 1->2->2->1) — the split is clean at the midpoint.
- Odd-length palindrome (e.g., 1->2->1) — the middle element is its own mirror.
- All nodes have the same value — always a palindrome regardless of length.
- Very long list — the O(1) space approach is crucial for memory efficiency.