Check whether a singly linked list is a palindrome in O(n) time and O(1) extra space.
intermediateFind the middle with slow and fast pointers, reverse the second half in place, compare it with the first half, then reverse it back to restore the list. Copying into an array is O(n) space; recursion is O(n) stack.
class ListNode { int val; ListNode next; ListNode(int v) { val = v; } }
static boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) return true;
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; }
ListNode second = reverse(slow.next);
boolean ok = true;
for (ListNode a = head, b = second; b != null; a = a.next, b = b.next)
if (a.val != b.val) { ok = false; break; }
slow.next = reverse(second); // restore
return ok;
}
static ListNode reverse(ListNode h) {
ListNode prev = null;
while (h != null) { ListNode n = h.next; h.next = prev; prev = h; h = n; }
return prev;
}- Why restore the list? Callers may still use it, and concurrent readers would otherwise see a corrupted list.
- Which middle for even length? The loop stops at the first of the two middle nodes, so the second half is the larger-index half; both halves have equal length.