Sweaty Imposter

Palindrome Linked List

EasyIn-Place Reversal of LinkedListNeetCode 150JuniorOpen on LeetCodeUpdated

You're given the head of a singly linked list of integers. Return true if the values read the same from head to tail as from tail to head, and false otherwise. A one-node list is a palindrome. Aim for O(n) time and O(1) extra space, which rules out copying the values into an array and comparing that.

Examples

head = [1,2,2,1] returns true

1221null

Forward the values are 1,2,2,1 and backward they are 1,2,2,1. The first value matches the last and the second matches the third.

head = [1,2] returns false

Forward reads 1,2 but backward reads 2,1. The first value 1 does not equal the last value 2.

head = [1,2,3,2,1] returns true

12321null
The middle 3 pairs with itself.

Both directions read 1,2,3,2,1. With an odd length the middle 3 has no partner, so it never needs to match anything.

Constraints

  • 1 <= n <= 10^5

Hints

Hint 1

Could you transform the second half so a single forward scan tells you the answer?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

Advance slow one node and fast two nodes at a time until fast runs out; slow then sits at the start of the second half (the middle node when the length is odd). Reverse the list from slow onward, then walk one pointer from head and one from the reversed half, comparing values until the reversed half ends. Any mismatch returns false. O(n) time, O(1) extra space, though the list is left with its second half reversed.

Time

O(n)

Space

O(1)

Pitfall

Looping until the first-half pointer is null. The first half still links into the middle node, so for even lengths it is one node longer than the reversed half; stop when the reversed pointer runs out.

Solutions

class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode prev = null, curr = slow;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        ListNode left = head, right = prev;
        while (right != null) {
            if (left.val != right.val) return false;
            left = left.next;
            right = right.next;
        }
        return true;
    }
}
Drill This