What’s New ?

The Top 10 favtutor Features You Might Have Overlooked

Read More

C++ Program to Check if a Linked List is Palindrome or Not

  • Jul 15, 2023
  • 7 Minutes Read
  • Why Trust Us
    We uphold a strict editorial policy that emphasizes factual accuracy, relevance, and impartiality. Our content is crafted by top technical writers with deep knowledge in the fields of computer science and data science, ensuring each piece is meticulously reviewed by a team of seasoned editors to guarantee compliance with the highest standards in educational content creation and publishing.
  • By Apurva Sharma
C++ Program to Check if a Linked List is Palindrome or Not

Every engineering student aspires to get a decent placement, but the journey to that goal isn’t very easy for most of us. There are so many technical interview questions, one of which we will understand today. Learn how to check if a String is a Palindrome or not using C++.

How to Check if a Linked List is Palindrome? 

This particular problem statement has been asked in technical interviews with many multinational companies like Google, Facebook, and Uber. Let’s understand first what exactly is a palindrome. 

A palindrome number is a number or a string that is equivalent to the string or number after reversing the string/number. For example, 12321, 565, 23432, 141, etc are the palindrome numbers. A palindrome can also be a string like MOM,   MADAM, LOL, etc. 

Palindrome linked list

 

Let’s discuss the problem statement: "We are given the head of a singly linked list of characters, write a function which returns a boolean value that indicates true if the given linked list is a palindrome, else false."

Now here is an example to better understand it.

Check if linked list is palindrome

 

The function will return it’s not a palindrome. 

There are two approaches to solve this problem, one involves the use of stack data structure and the other involves reversing the list and verifying the occurrence of the elements. There is one more approach to solving this problem using a recursive function call. Let’s discuss the algorithms!

6 Ways to Check Linked List is Palindrome

There are 6 different ways available in programming to check whether a given linked list is a palindrome or not. Let's learn them one by one.

1) Using Stack

In this algorithm, we use a stack of list elements. There are three operations needed to be formed to implement our algorithm.

  1. Iterate through all the elements in the given list from the head pointer to the tail and push every element to the stack as we traverse.
  2. Now we traverse the list again. And at each node, we pop an element from the stack and compare the element in the popped node with the current node.
  3. If all the nodes match, then we return the boolean value true, or else return false.

Here is the C++ program for this method:

#include<bits/stdc++.h>
 
using namespace std;
 
// Declaration of a single Node
class Node {
public:
        int data;
        Node(int d){
            data = d;
        }
        Node *ptr;
};
 
// Function that returns boolean value
bool isPalin(Node* head){
        
        // Temp pointer
        Node* slow= head;
 
        // Create a stack
        stack <int> s;
 
 
        // First traversal to push all the elements to stack
        while(slow != NULL){
                s.push(slow->data);
                slow = slow->ptr;
        }
 
        // Second Traversal to compare the stack and node
        while(head != NULL ){
            
            int i=s.top();
            s.pop();
 
            // Compare data
            if(head -> data != i){
                return false;
            }
        head=head->ptr;
        }
 
return true;
}
 
// Driver Function
int main(){
    // Create nodes
    Node one = Node(31);
    Node two = Node(32);
    Node three = Node(33);
    Node four = Node(34);
    Node five = Node(35);
 
    // Connect all the nodes
    five.ptr = NULL;
    one.ptr = &two;
    two.ptr = &three;
    three.ptr = &four;
    four.ptr = &five;
    Node* temp = &one;
 
    
    // Call function to return bool if the list is palindrome or not
    int result = isPalin(&one);
 
    if(result == 1)
            cout<<"The value is True\n";
    else
        cout<<"The value is False\n";
 
return 0;
}

 

Output: 

The value is not a palindrome.

 

The time complexity of the algorithm is O(N) because we iterate through each element at least once. As we push the elements into the stack one by one we are bound to iterate over the complete linked list at least once and therefore the time complexity of the algorithm is O(N) and since we are using a stack to push all the elements, the space complexity of the algorithm is also O(N).

2) Reversing the list 

In this algorithm, we simply reverse half of the linked list. There are four operations needed to be formed to implement our algorithm.

  1. Find the middlemost element of the linked list. 
  2. Then we reverse the second half of the linked list. 
  3. We verify if the first half and second half are equivalent by comparing node by node. 
  4. Then we reconstruct the original linked list by inverting the second half once more and attaching it back to the first half

We divide this list into halves by keeping the count if the count variable is even, and then the first and second halves would exactly have half elements, and in case of an odd number of elements we use a variable ‘midnode’. Below is the C++ code to implement it:

#include<bits/stdc++.h>
 
using namespace std;
 
 
struct ListNode {
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};
 
// Function to find the mid of linked-list
ListNode* find_middle(ListNode* head,int n)
        {
            ListNode *slow=head,*fast=head;
            while(fast!=NULL && fast->next!=NULL)
            {
                slow=slow->next;
                fast=fast->next->next;
            } 
            if(n&1)
                return slow->next;
            else
                return slow;
        }
// Function to Reverse the List using three pointers
ListNode* reverse_link(ListNode* head)
        {
            ListNode *prev=NULL;
            ListNode *curr=head;
            ListNode *next=NULL;
            while(curr!=NULL)
            {
                next=curr->next;
                curr->next=prev;
                prev=curr;
                curr=next;
            }
            return prev;
        }
// Return if the Linked List is palindrome  
bool isPalindrome(ListNode* head) {
        if(head==NULL || head->next==NULL)
            return true;
        
        ListNode *temp=head;
        // Iterate to count odd/even
        int n=0;
        while(temp!=NULL)
        {
            temp=temp->next;
            n++;
        }
        temp=head;
        // Find the mid elemeny
        ListNode *head_mid=find_middle(temp,n);
        // Reverse the second half linked-list
        ListNode *head_rev=reverse_link(head_mid);
        // Verify first half and second half of linked-list are equivalent
        while(head_rev!=NULL)
        { 
 
            if(head->val!=head_rev->val)
                return false;
            
            head_rev=head_rev->next;
            head=head->next;
        }
        return true;
    }
 
// Driver Function
int main(){
    // Create nodes
    ListNode one = ListNode(31);
    ListNode two = ListNode(32);
    ListNode three = ListNode(33);
    ListNode four = ListNode(32);
    ListNode five = ListNode(31);
 
    ListNode *one_ptr = &one; 
    ListNode *two_ptr = &two; 
    ListNode *three_ptr = &three; 
    ListNode *four_ptr = &four; 
    ListNode *five_ptr = &five; 
 
    // Connect all the nodes
    five_ptr->next = NULL;
    one_ptr->next = &two;
    two_ptr->next = &three;
    three_ptr->next = &four;
    four_ptr->next = &five;
    ListNode* temp = &one;
 
    
    // Call function to return bool if the list is palindrome or not
    int result = isPalindrome(&one);
 
    if(result == 1)
            cout<<"The value is Palindrome\n";
    else
        cout<<"The value is NOT Palindrome\n";
 
return 0;
}
 

 

Output:

The value is palindrome.

 

The time complexity of this algorithm is O(N) because we iterate through each of the elements in the linked list at least half the time. As we divide the linked list into two halves and keep the count of the variable and check if it is even, hence the time complexity is O(N). The space complexity of the algorithm is O(1) because we don’t use any extra space to find the outcome.

4) Recursion

The recursive method to check for palindromes in a linked list involves examining the linked list's first and last members. If they match, those entries are removed and the procedure with the remaining linked list is called recursively. The process is repeated until the linked list is empty or we come across an unrelated pair of entries.

Here is the C++ code to determine whether a singly linked list contains a palindrome:

bool isPalindromeRecursiveHelper(ListNode* &left, ListNode* right) {
    if (right == nullptr) {
        return true;
    }
    
    bool isPal = isPalindromeRecursiveHelper(left, right->next);
    if (!isPal) {
        return false;
    }
    
    isPal = (left->val == right->val);
    left = left->next;
    return isPal;
}

bool isPalindromeRecursive(ListNode* head) {
    return isPalindromeRecursiveHelper(head, head);
}

 

The helper method isPalindromeRecursiveHelper in this code accepts two pointers, left and right. The right initially points to the final element of the linked list, while the left initially points to the linked list's head. If the linked list contains a palindrome, the function returns true; if not, it returns false.

5)Extra Data Structure

This strategy involves building a stack and pushing the first portion of the linked list onto it. Then, we iterate across the linked list's second half and compare each entry to the stack's top element. The linked list is a palindrome if every entry matches.

Here is some C++ code that uses an additional data structure:

bool isPalindromeStack(ListNode* head) {
    stack<int> s;
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast != nullptr && fast->next != nullptr) {
        s.push(slow->val);
        slow = slow->next;
        fast = fast->next->next;
    }
    
    if (fast != nullptr) {
        slow = slow->next;
    }
    
    while (slow != nullptr) {
        if (s.top() != slow->val) {
            return false;
        }
        s.pop();
        slow = slow->next;
    }
    
    return true;
}

 

In this code, the linked list is iterated over using two pointers, slow and fast. Fast moves two steps in a single motion, while slow moves one. Until fast reaches the end of the linked list, we push the elements slowly pointed onto the stack. We omit the middle element if the linked list contains an odd number of elements.

Then, we make a comparison between the linked list's remaining elements and those on the stack. The linked list is a palindrome if they coincide.

6) Reversing the Second Half

This method's goal is to discover the center element by repeatedly iterating through the linked list. After that, we compare the first and second halves of the linked list in reverse. The linked list is a palindrome if they coincide.

Below is the C++ function to implement it:

bool isPalindromeReverse(ListNode* head) {
    if (head == nullptr || head->next == nullptr) {
        return true;
    }
    
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast != nullptr && fast->next != nullptr) {
        slow = slow->next;
        fast = fast->next->next;
    }
    
    ListNode* prev = nullptr;
    ListNode* cur = slow;
    while (cur != nullptr) {
        ListNode* next = cur->next;
        cur->next = prev;
        prev = cur;
        cur = next;
    }
    
    ListNode* p1 = head;
    ListNode* p2 = prev;
    while (p2 != nullptr) {
        if (p1->val != p2->val) {
            return false;
        }
        p1 = p1->next;
        p2 = p2->next;
    }
    
    return true;
}

 

To locate the middle element of the linked list, this code makes use of two pointers, slow and fast. Fast moves two steps in a single motion, while slow moves one. Slow identifies the middle element when fast reaches the end of the linked list.

Then, by iterating from slow through the end of the linked list and switching the orientation of the pointers, we reverse the second half of the linked list. The previous element is tracked using prior, the current element is tracked using cur, and the next element is tracked using next.

Finally, we compare each member after iterating through the first half of the linked list (p1) and the inverted second half (p2). The linked list is a palindrome if they coincide.

Conclusion

In this tutorial, we discussed the definition of a palindrome and how can we check if the linked list is a palindrome or not using two approaches and discussed its code in C++. We observed that both approaches have a time complexity of O(N) whereas if we use the second approach ie reversing the list takes less space as compared to the first approach.

FavTutor - 24x7 Live Coding Help from Expert Tutors!

About The Author
Apurva Sharma
Hi, I am Apurva Sharma, a data science engineer, deep learning evangelist and DevOps enthusiast