Given the head
of a singly linked list, determine if it is a palindrome. A palindrome reads the same forwards and backward.
For example, the linked list [1, 2, 2, 1]
is a palindrome, while [1, 2]
is not.
Write a function that takes the head of a singly linked list as input and returns true
if it is a palindrome and false
otherwise.
Example 1:
Input: head = [1,2,2,1]
Output: true
Example 2:
Input: head = [1,2]
Output: false
Constraints:
[1, 10^5]
.0 <= Node.val <= 9
Follow up: Can you solve it in O(n) time and O(1) space?
One straightforward approach is to convert the linked list into an array and then check if the array is a palindrome. This is similar to checking if a string is a palindrome using two pointers from the start and end.
Code (Python):
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def isPalindrome(head):
arr = []
curr = head
while curr:
arr.append(curr.val)
curr = curr.next
left, right = 0, len(arr) - 1
while left < right:
if arr[left] != arr[right]:
return False
left += 1
right -= 1
return True
Time Complexity: O(n) to convert the linked list to an array and O(n) to check if the array is a palindrome, so the overall time complexity is O(n).
Space Complexity: O(n) to store the linked list elements in an array.
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.
Code (Python):
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def isPalindrome(head):
if not head or not head.next:
return True
# Find middle (slow pointer)
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# Reverse the second half
prev = None
curr = slow
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
# Compare first and second half
first_half = head
second_half = prev # prev is the head of reversed second half
while second_half:
if first_half.val != second_half.val:
return False
first_half = first_half.next
second_half = second_half.next
return True
Edge Cases:
head == None
. Returns True
as an empty list is a palindrome.head.next == None
. Returns True
as a single element list is a palindrome.Time Complexity:
Therefore, the overall time complexity is O(n).
Space Complexity: O(1) as we are only using a constant amount of extra space.