PALINDROME LIST

In this blog, we have to figure out a palindrome linked list. A Palindrome linked list means a Linked List which has values in a palindromic form i.e. values from left to right will be the same as the values from right to left in the linked list. Let’s discuss how to find a palindrome linked list.

How to check Palindrome Linked List

Check whether the given linked list is a palindrome or not.

Example:

2
3
2 5 2  true
5
4 5 6 3 4  false

First list is a palindrome since the first element is same as the last and middle one is common.
Second list is not a palindrome because the second element does not match the fourth element in the list.

See original problem statement here

EXPLANATION:

Approach 1(Linked list reversal) For Palindrome Linked List:

Get the middle of the linked list.

Reverse the second half of the linked list.

Check if the first half and second half are identical.

Construct the original linked list by reversing the second half again and attaching it back to the first half.

Note: This approach takes O(n) time and O(1) extra space.

Approach 2(Using recursion) For Palindrome Linked List:

Use two pointers left and right. Move right and left using recursion and check for following in each recursive call.Sub-list is palindrome.Value at current left and right are matching.
If both above conditions are true then return true.

    bool isPalindrome(Node*& left, Node* right)
    {
    // base case
    if (right == nullptr)
        return true;

    // return false on first mismatch
    if (!isPalindrome(left, right->next))
        return false;

    // copy left pointer
    Node* prevLeft = left;

    // advance the left pointer to the next node
    // this change would reflect in the parent recursive calls
    left = left->next;

    // In order for linked list to be palindrome, the character at the left
    // node should match with the character at the right node
    return (prevLeft->data == right->data);
    }

Approach 3(Using stack) For Palindrome Linked List:

A simple solution is to use a stack of list nodes. This mainly involves three steps.Traverse the given list from head to tail and push every visited node to stack.Traverse the list again. For every visited node, pop a node from the stack and compare data of popped nodes with currently visited node.If all nodes matched, then return true, else false.

Note: This approach takes O(n) time and O(n) extra space(stack).

SOLUTIONS For Palindrome Linked List:

#include <stdio.h>  
    #include <stdbool.h>
    struct node{  
    int data;  
    struct node *next;  
    }; 
    struct node *head, *tail = NULL;  
    int size = 0;  
    void addNode(int data) {
    struct node *newNode = (struct node*)malloc(sizeof(struct node));  
    newNode->data = data;  
    newNode->next = NULL; 
    if(head == NULL) {  
        head = newNode;  
        tail = newNode;  
    }  
    else { 
        tail->next = newNode;
        tail = newNode;  
    } 
    size++;  
    } 
    struct node* reverseList(struct node *temp){  
    struct node *current = temp;  
    struct node *prevNode = NULL, *nextNode = NULL;
    while(current != NULL){  
        nextNode = current->next;  
        current->next = prevNode;  
        prevNode = current;  
        current = nextNode;  
    }  
    return prevNode;  
    } 
    void isPalindrome(){  
    struct node *current = head;  
    bool flag = true;
    int mid = (size%2 == 0)? (size/2)-1 : ((size)/2); 
    for(int i=1; i<mid; i++){  
        current = current->next;  
    } 
    struct node *revHead = reverseList(current->next);   
    while(head != NULL && revHead != NULL){  
        if(head->data != revHead->data){  
            flag = false;  
            break;  
        }  
        head = head->next;  
        revHead = revHead->next;  
    }  

    if(flag)  
        printf("true\n");  
    else  
        printf("false\n");  
    }  

    int main()  
    {  
    //Add nodes to the list
    int t;
    scanf("%d",&t);
    while(t--)
    {
      int n;scanf("%d",&n);

      for(int i=0;i<n;i++)
      {
        int x;scanf("%d",&x);
        addNode(x);  
      }size=n;
      isPalindrome();
    }
    return 0;  
    }  
#include<bits/stdc++.h>
    using namespace std;
    struct node{  
    int data;  
    struct node *next;  
    }; 
    struct node *head, *tail = NULL;  
    int size = 0;  
    void addNode(int data) {
    node *newNode = new node();  
    newNode->data = data;  
    newNode->next = NULL; 
    if(head == NULL) {  
        head = newNode;  
        tail = newNode;  
    }  
    else { 
        tail->next = newNode;
        tail = newNode;  
    } 
    size++;  
    } 
    struct node* reverseList(struct node *temp){  
    struct node *current = temp;  
    struct node *prevNode = NULL, *nextNode = NULL;
    while(current != NULL){  
        nextNode = current->next;  
        current->next = prevNode;  
        prevNode = current;  
        current = nextNode;  
    }  
    return prevNode;  
     } 
    void isPalindrome(){  
    struct node *current = head;  
    bool flag = true;
    int mid = (size%2 == 0)? (size/2)-1 : ((size)/2); 
    for(int i=1; i<mid; i++){  
        current = current->next;  
    } 
    struct node *revHead = reverseList(current->next);   
    while(head != NULL && revHead != NULL){  
        if(head->data != revHead->data){  
            flag = false;  
            break;  
        }  
        head = head->next;  
        revHead = revHead->next;  
    }  

    if(flag)  
        printf("true\n");  
    else  
        printf("false\n");  
    }  

    int main()  
    {  
    //Add nodes to the list
    int t;
    cin>>t;
    while(t--)
    {
      int n;cin>>n;

      for(int i=0;i<n;i++)
      {
        int x;cin>>x;
        addNode(x);  
      }size=n;
      isPalindrome();
    }
    return 0;  
    }  
 
import java.io.*;
    import java.util.*;
    public class Main{
    static class SinglyLinkedListNode {
        public int data;
        public SinglyLinkedListNode next;
        public SinglyLinkedListNode(int nodeData) {
            this.data = nodeData;
            this.next = null;
        }
    }
    static class SinglyLinkedList {
        public SinglyLinkedListNode head;
        public SinglyLinkedListNode tail;
        public SinglyLinkedList() {
            this.head = null;
            this.tail = null;
        }
        public void insertNode(int nodeData) {
            SinglyLinkedListNode node = new SinglyLinkedListNode(nodeData);

            if (this.head == null) {
                this.head = node;
            } else {
                this.tail.next = node;
            }

            this.tail = node;
        }
    }

    static boolean palindromeLlist(SinglyLinkedListNode head) {

        SinglyLinkedListNode slow = head;
        boolean ispalin = true;
        Stack<Integer> stack = new Stack<Integer>();

        while (slow != null) {
            stack.push(slow.data);
            slow = slow.next;
        }

        while (head != null) {

            int i = stack.pop();
            if (head.data == i) {
                ispalin = true;
            }
            else {
                ispalin = false;
                break;
            }
            head = head.next;
        }
        return ispalin;
    }

    private static final Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) throws IOException {
        int testCases = scanner.nextInt();
        while (testCases-- > 0) {
            SinglyLinkedList llist = new SinglyLinkedList();
            int llistCount = scanner.nextInt();
            for (int i = 0; i < llistCount; i++) {
                int llistItem = scanner.nextInt();
                llist.insertNode(llistItem);
            }
            boolean res =palindromeLlist(llist.head);
            if(res)
                System.out.println("true");
            else
                System.out.println("false");
        }
        scanner.close();
    }
    }
 
class Node:

	def __init__(self, data):
		
		self.data = data
		self.next = None

class LinkedList:

	def __init__(self):
		
		self.head = None

	def isPalindrome(self, head):
		
		slow_ptr = head
		fast_ptr = head
		prev_of_slow_ptr = head
		
		midnode = None
		
		res = True
		
		if (head != None and head.next != None):
			
			while (fast_ptr != None and
				fast_ptr.next != None):
				fast_ptr = fast_ptr.next.next
				prev_of_slow_ptr = slow_ptr
				slow_ptr = slow_ptr.next

			if (fast_ptr != None):
				midnode = slow_ptr
				slow_ptr = slow_ptr.next
				
			second_half = slow_ptr
			prev_of_slow_ptr.next = None
			second_half = self.reverse(second_half)
			res = self.compareLists(head, second_half)
			second_half = self.reverse(second_half)
			
			if (midnode != None):
				
				prev_of_slow_ptr.next = midnode
				midnode.next = second_half
			else:
				prev_of_slow_ptr.next = second_half
		return res
	
	def reverse(self, second_half):
		
		prev = None
		current = second_half
		next = None
		
		while current != None:
			next = current.next
			current.next = prev
			prev = current
			current = next
			
		second_half = prev
		return second_half

	def compareLists(self, head1, head2):
		
		temp1 = head1
		temp2 = head2
		
		while (temp1 and temp2):
			if (temp1.data == temp2.data):
				temp1 = temp1.next
				temp2 = temp2.next
			else:
				return 0
				
		if (temp1 == None and temp2 == None):
			return 1
			
		return 0
	
	def push(self, new_data):
		
		new_node = Node(new_data)
		new_node.next = self.head
		self.head = new_node

	def printList(self):
		
		temp = self.head
		
		while(temp):
			print(temp.data, end = "->")
			temp = temp.next
			
		print("NULL")

if __name__ == '__main__':
	
	l = LinkedList()
	s = [ 'a', 'b', 'a', 'c', 'a', 'b', 'a' ]
	
	for i in range(7):
		l.push(s[i])
		l.printList()
		
		if (l.isPalindrome(l.head) != False):
			print("Is Palindrome\n")
		else:
			print("Not Palindrome\n")
		print()

This article tried to discuss different approaches for finding palindrome linked list by which topics like stack, recursion and linked list are improved. Having knowledge about the topics like stack, recursion, and linked list will give an upper hand in the technical interviews. To practice more problems on Linked List, Recursion, Stack you can check out MYCODE | Competitive Programming.

FAQ

1. Can linked list be palindromes?
To check if a linked list is palindrome or not, we need to compare the first element with the last element, the second element with the second last element, the third element with the third last element, etc. If all the comparisons are equal, then the linked list is palindrome; otherwise, not.

2. Which companies asked in their interview for finding palindromic linked list?
IBM, Mcafee, Infosys, TCS and Gemini Solutions have recently asked this question in their interview.

Leave a Reply

Your email address will not be published. Required fields are marked *