Given the head
of a singly linked list, determine if it is a palindrome.
A palindrome is a sequence that reads the same forwards and backward.
Examples:
Input: head = [1, 2, 2, 1]
Output: true
Explanation: The linked list represents the sequence 1 -> 2 -> 2 -> 1, which is a palindrome.
Input: head = [1, 2]
Output: false
Explanation: The linked list represents the sequence 1 -> 2, which is not a palindrome.
Constraints:
[1, 10^5]
.0 <= Node.val <= 9
Can you solve it in O(n) time and O(1) space?
One straightforward approach is to traverse the linked list and store the values in an array. Then, we can use two pointers, one at the beginning and one at the end of the array, to check if the array forms a palindrome.
Steps:
left
at 0 and right
at array.length - 1
.left < right
, compare array[left]
and array[right]
.
false
.left
and decrement right
.true
.Code (Java):
import java.util.ArrayList;
import java.util.List;
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
class Solution {
public boolean isPalindrome(ListNode head) {
List<Integer> list = new ArrayList<>();
ListNode current = head;
while (current != null) {
list.add(current.val);
current = current.next;
}
int left = 0;
int right = list.size() - 1;
while (left < right) {
if (!list.get(left).equals(list.get(right))) {
return false;
}
left++;
right--;
}
return true;
}
}
To achieve O(1) space complexity, we can reverse the second half of the linked list and then compare the first half with the reversed second half.
Steps:
Code (Java):
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode slow = head;
ListNode fast = head;
// Find the middle of the linked list
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// Reverse the second half
ListNode prev = null;
ListNode current = slow;
ListNode next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
// Compare the first half and the reversed second half
ListNode firstHalf = head;
ListNode secondHalf = prev;
while (secondHalf != null) {
if (firstHalf.val != secondHalf.val) {
return false;
}
firstHalf = firstHalf.next;
secondHalf = secondHalf.next;
}
return true;
}
}
true
.true
.