PALINDROME LIST

Concepts Used

Linked list,recursion ,stack.

Difficulty Level

Easy

Problem Statement :

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):

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):

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):

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 stack and compare data of popped node 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:

#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()

[forminator_quiz id="1797"]
This article tried to discuss Linked List, Recursion, Stack. Hope this blog helps you understand and solve the problem. To practice more problems on Linked List, Recursion, Stack you can check out MYCODE | Competitive Programming.

Leave a Reply

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