I'm trying to check if a singly linked list is a palindrome or not. The constraints are - the algorithm has to be in linear time and constant space.
The basic algorithm I'm using is as below -
- Use fast & slow pointers to divide the list into two halves.
- Reverse the second half in-place.
- Compare the first and second half.
- Construct back the original list
- Return the result.
My implementation works for when the list has even number of elements but fails if the number of elements is odd.
/*
* @brief Checks if a list is a palindrome or not
*/
bool is_palindrome(node *head)
{
node *first; /* Points to head node of 1st half */
node *second; /* Points to head node of 2nd half */
node *f_ptr = head; /* Fast pointer */
node *s_ptr = head; /* Slow pointer */
node *prev = NULL; /* Previous to slow pointer */
bool ret = false; /* Return value */
while (f_ptr && f_ptr->next && f_ptr->next->next)
{
prev = s_ptr;
s_ptr = s_ptr->next;
f_ptr = f_ptr->next->next;
}
/* List with even number of elements */
if (!(f_ptr->next->next))
{
first = head;
second = s_ptr->next;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
s_ptr->next = second;
print_list(head);
}
/* List with odd number of elements */
if (!(f_ptr->next))
{
first = head;
second = s_ptr->next;
prev->next = NULL;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
prev->next = s_ptr; s_ptr->next = second;
print_list(head);
}
return ret;
}
Can someone please help me figure out what I am doing wrong while handling the odd number case? The complete implementation of this program can be found here.