Palindrome Linked List

Updated on 30 June, 2025
Palindrome Linked List header image

Problem Statement

In this task, we are given the head of a singly linked list and are tasked to determine whether the sequence of values in this linked list forms a palindrome. A palindrome is a sequence that reads the same backward as forward, meaning that the first element is equal to the last, the second is equal to the second-last, and so on.

Examples

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

Approach and Intuition

Given the nature of singly linked lists—where each node points only to the next node—it is not trivial to traverse the list backwards. Therefore, our challenge is to verify the palindrome property without direct backward traversal.

Example 1:

  • Input: head = [1,2,2,1]
  • Output: true

Analysis:

  • For a list [1,2,2,1], if we read from start to end, it is 1,2,2,1, and from end to start, it’s the same.
  • Therefore, the list is a palindrome.

Example 2:

  • Input: head = [1,2]
  • Output: false

Analysis:

  • For a list [1,2], reading from start to end gives 1,2, whereas end to start gives 2,1.
  • Thus, the sequence is not a palindrome.
  1. A naive approach would involve copying the linked list into an array. This changes the space complexity drastically since we are using auxiliary space proportional to the size of the linked list.

  2. Another possible solution could involve a more space-efficient approach, such as reversing the second half of the linked list:

    • Find the middle of the linked list using a slow and fast pointer approach. Fast pointer moves two steps for every step the slow pointer moves.
    • Reverse the second part of the linked list.
    • Compare the first part with the reversed second part; if both halves are identical, then the list is a palindrome.

Understanding these approaches and translating them into an efficient ascent matters because palindromic properties in linked list structures are not straightforward due to their linear and forward-only nature.

Solutions

  • Java
  • Python
java
class Solution {
    
    public boolean checkPalindrome(ListNode node) {
    
        if (node == null) return true;
    
        // Process the first half and reverse the second half.
        ListNode halfEnd = findMiddle(node);
        ListNode secondPart = reverse(node.next);
    
        // Verify palindrome condition.
        ListNode firstPointer = node;
        ListNode secondPointer = secondPart;
        boolean isPalindrome = true;
        while (isPalindrome && secondPointer != null) {
            if (firstPointer.val != secondPointer.val) isPalindrome = false;
            firstPointer = firstPointer.next;
            secondPointer = secondPointer.next;
        }        
    
        // Reconstruct the original list and return result.
        halfEnd.next = reverse(secondPart);
        return isPalindrome;
    }
    
    // Reverse the linked list.
    private ListNode reverse(ListNode node) {
        ListNode previous = null;
        ListNode current = node;
        while (current != null) {
            ListNode nextNode = current.next;
            current.next = previous;
            previous = current;
            current = nextNode;
        }
        return previous;
    }
    
    // Find the midpoint of the list (end of the first half).
    private ListNode findMiddle(ListNode node) {
        ListNode fast = node;
        ListNode slow = node;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}

The provided Java code presents a solution to check if a linked list is a palindrome. This involves confirming whether the list reads the same forwards and backwards.

  • The checkPalindrome method begins by confirming if the linked list is empty, in which case, it immediately returns true because an empty list is technically a palindrome.
  • It then finds the middle of the list using the findMiddle method and reverses the second half of the list starting from the node immediately following this midpoint.
  • Proceed to compare the values of the nodes from the start of the list and from the start of the reversed half. Continue this comparison until the end of the reversed list is reached or a mismatch is found.
  • After checking, the second half of the list is reversed again to restore the original list structure before returning the result of the palindrome check.

The reverse method reverses any given segment of the linked list, and the findMiddle method locates the middle point, useful to split the list into roughly two equal parts for the comparison process.

Manage the modifications to the list carefully and ensure that the original data structure of the linked list is restored by the end of the operation. This is crucial for maintaining data integrity if the linked list is to be used after the palindrome check.

python
class Solution:
    
    def checkPalindrome(self, node: ListNode) -> bool:
        if node is None:
            return True
    
        half_end = self.find_half_end(node)
        reverse_start = self.reverse_linked_list(half_end.next)
    
        palindrome_check = True
        first_head = node
        second_head = reverse_start
        while palindrome_check and second_head is not None:
            if first_head.val != second_head.val:
                palindrome_check = False
            first_head = first_head.next
            second_head = second_head.next
    
        half_end.next = self.reverse_linked_list(reverse_start)
        return palindrome_check    
    
    def find_half_end(self, node: ListNode) -> ListNode:
        rapid = node
        slow = node
        while rapid.next is not None and rapid.next.next is not None:
            rapid = rapid.next.next
            slow = slow.next
        return slow
    
    def reverse_linked_list(self, node: ListNode) -> ListNode:
        prev = None
        curr = node
        while curr is not None:
            next_temp = curr.next
            curr.next = prev
            prev = curr
            curr = next_temp
        return prev

This Python implementation checks if a singly linked list is a palindrome. The algorithm involves identifying the middle of the list, reversing the second half, and then comparing it with the first half for equality. Follow the steps outlined in the provided code:

  1. Define the method checkPalindrome which checks if the linked list starting from the given node is a palindrome.

    • Immediately return True if the input node is None. An empty list is considered a palindrome.
    • Find the end node of the first half of the list using the find_half_end method.
    • Reverse the second half of the list starting from the node next to the found end node using the reverse_linked_list method.
  2. Iterate simultaneously through the nodes of the first half and the reversed second half.

    • A mismatch between values of corresponding nodes in these two halves indicates the list isn't a palindrome.
  3. Restore the list to its original structure by reversing the second half back and linking it to the first half.

  4. The find_half_end method locates the end of the first half using the slow and rapid (fast) pointer technique. Slow pointer moves one step at a time, while rapid pointer moves two steps.

  5. reverse_linked_list reverts the part of the list passed to it by adjusting pointers of each node.

By using these methods, the space complexity is minimized, effectively using just O(1) additional space aside from the input list. The time complexity is O(n), where n is the number of nodes in the list, since each node is visited a constant number of times. This solution ensures that the structure of the original linked list is maintained after the palindrome check.

Comments

No comments yet.