Given a singly linked list, we have to check whether it is a palindrome or not.
Examples:
Input:
Output: true
Explanation: It forms the same sequence when read from front to back and from back to front.
Input:
Output: false
Explanation: Not and Palindrome
[Approach - 1] Using Stack - O(n) Time and O(n) Space
The idea is to use stack and start traversing from the head node. Push all the node and then start comparing from the head node with top value of stack.
Steps to solve the problem:
- Push all the node's data into the stack.
- Again traverse from the head node.
- Compare the popped node's data with the current node's data.
- If both are not equal ,return false .
- If all elements match ,return
true
.
Below is the implementation of the above approach :
C++
#include <iostream>
#include <stack>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int d) {
data = d;
next = nullptr;
}
};
// Function to check if the linked list
// is palindrome or not
bool isPalindrome(Node* head) {
Node* currNode = head;
// Declare a stack
stack<int> s;
// Push all elements of the list to the stack
while (currNode != nullptr) {
s.push(currNode->data);
currNode = currNode->next;
}
// Iterate in the list again and check by
// popping from the stack
while (head != nullptr) {
// Get the topmost element
int c = s.top();
s.pop();
// Check if data is not same as popped element
if (head->data != c) {
return false;
}
// Move ahead
head = head->next;
}
return true;
}
int main() {
// Linked list : 1->2->3->2->1
Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(2);
head->next->next->next->next = new Node(1);
bool result = isPalindrome(head);
if (result)
cout << "true\n";
else
cout << "false\n";
return 0;
}
Java
import java.util.Stack;
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
class GfG {
// Function to check if the linked list
// is palindrome or not
static boolean isPalindrome(Node head) {
Node currNode = head;
Stack<Integer> s = new Stack<>();
// Push all elements of the list to the stack
while (currNode != null) {
s.push(currNode.data);
currNode = currNode.next;
}
// Iterate in the list again and check
// by popping from the stack
while (head != null) {
// Get the topmost element
int c = s.pop();
// Check if data is not same as
// popped element
if (head.data != c) {
return false;
}
// Move ahead
head = head.next;
}
return true;
}
public static void main(String[] args) {
// Linked list : 1->2->3->2->1
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
boolean result = isPalindrome(head);
if (result)
System.out.println("true");
else
System.out.println("false");
}
}
Python
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Function to check if the linked list
# is palindrome or not
def isPalindrome(head):
curr_node = head
s = []
# Push all elements of the list to the stack
while curr_node is not None:
s.append(curr_node.data)
curr_node = curr_node.next
# Iterate in the list again and check by'
# popping from the stack
while head is not None:
# Get the topmost element
c = s.pop()
# Check if data is not same as popped element
if head.data != c:
return False
# Move ahead
head = head.next
return True
# Linked list : 1->2->3->2->1
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(2)
head.next.next.next.next = Node(1)
result = isPalindrome(head)
if result:
print("true")
else:
print("false")
C#
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node next;
public Node(int d) {
data = d;
next = null;
}
}
// Class to check if the linked list
// is palindrome or not
class GfG {
// Function to check if the linked list
// is palindrome or not
static bool isPalindrome(Node head) {
Node currNode = head;
Stack<int> s = new Stack<int>();
// Push all elements of the list to the stack
while (currNode != null) {
s.Push(currNode.data);
currNode = currNode.next;
}
// Iterate in the list again and check by
// popping from the stack
while (head != null) {
// Get the topmost element
int c = s.Pop();
// Check if data is not same as
// popped element
if (head.data != c) {
return false;
}
// Move ahead
head = head.next;
}
return true;
}
static void Main(string[] args) {
// Linked list : 1->2->3->2->1
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
bool result = isPalindrome(head);
if (result)
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
JavaScript
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
// Function to check if the linked list is
// palindrome or not
function isPalindrome(head) {
let currNode = head;
let stack = [];
// Push all elements of the list to the stack
while (currNode !== null) {
stack.push(currNode.data);
currNode = currNode.next;
}
// Iterate in the list again and check by
// popping from the stack
while (head !== null) {
// Get the topmost element
let c = stack.pop();
// Check if data is not same as popped element
if (head.data !== c) {
return false;
}
// Move ahead
head = head.next;
}
return true;
}
// Linked list : 1->2->3->2->1
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
let result = isPalindrome(head);
if (result)
console.log("true");
else
console.log("false");
[Approach - 2] Using Recursion - O(n) Time and O(n) Space
The idea is to initialize a pointer start, which will initially point to the head of the node. Then, recursively traverse the list. At each node end, first recursively check if the right side of the list is palindrome. If yes, then compare the values of the start and end node. If they are equal, then set start = start.nextand return true. Otherwise return false.
C++
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int d) {
data = d;
next = nullptr;
}
};
// Recursive Function to check whether
// the list is palindrome
bool isPalindromeRecur(Node* end, Node* &start) {
// base case
if (end == nullptr) return true;
// Recursively check the right side.
bool right = isPalindromeRecur(end->next, start);
// Compare the start and end nodes.
bool ans = right && start->data == end->data;
// Update the start node
start = start->next;
return ans;
}
// Function to check whether the list is palindrome
bool isPalindrome(Node* head) {
// Set starting node to head
Node* start = head;
// Recursively check the ll and return
return isPalindromeRecur(head, start);
}
int main() {
// Linked list : 1->2->3->2->1
Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(2);
head->next->next->next->next = new Node(1);
bool result = isPalindrome(head);
if (result)
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}
Java
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
class GfG {
// Recursive Function to check whether
// the list is palindrome
static boolean isPalindromeRecur(Node end, Node[] start) {
// base case
if (end == null) return true;
// Recursively check the right side.
boolean right = isPalindromeRecur(end.next, start);
// Compare the start and end nodes.
boolean ans = right && start[0].data == end.data;
// Update the start node
start[0] = start[0].next;
return ans;
}
// Function to check whether the list is palindrome
static boolean isPalindrome(Node head) {
// Set starting node to head
Node[] start = new Node[]{head};
// Recursively check the ll and return
return isPalindromeRecur(head, start);
}
public static void main(String[] args) {
// Linked list : 1->2->3->2->1
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
boolean result = isPalindrome(head);
if (result)
System.out.println("true");
else
System.out.println("false");
}
}
Python
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Recursive Function to check whether
# the list is palindrome
def isPalindromeRecur(end, start):
# base case
if end is None:
return True
# Recursively check the right side.
right = isPalindromeRecur(end.next, start)
# Compare the start and end nodes.
ans = right and start[0].data == end.data
# Update the start node
start[0] = start[0].next
return ans
# Function to check whether the list is palindrome
def isPalindrome(head):
# Set starting node to head
start = [head]
# Recursively check the ll and return
return isPalindromeRecur(head, start)
if __name__ == "__main__":
# Linked list : 1->2->3->2->1
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(2)
head.next.next.next.next = Node(1)
result = isPalindrome(head)
if result:
print("true")
else:
print("false")
C#
class Node {
public int data;
public Node next;
public Node(int d) {
data = d;
next = null;
}
}
class GfG {
// Recursive Function to check whether
// the list is palindrome
static bool isPalindromeRecur(Node end, ref Node start) {
// base case
if (end == null) return true;
// Recursively check the right side.
bool right = isPalindromeRecur(end.next, ref start);
// Compare the start and end nodes.
bool ans = right && start.data == end.data;
// Update the start node
start = start.next;
return ans;
}
// Function to check whether the list is palindrome
static bool isPalindrome(Node head) {
// Set starting node to head
Node start = head;
// Recursively check the ll and return
return isPalindromeRecur(head, ref start);
}
static void Main(string[] args) {
// Linked list : 1->2->3->2->1
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
bool result = isPalindrome(head);
if (result)
System.Console.WriteLine("true");
else
System.Console.WriteLine("false");
}
}
JavaScript
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
// Recursive Function to check whether
// the list is palindrome
function isPalindromeRecur(end, start) {
// base case
if (end === null) return true;
// Recursively check the right side.
let right = isPalindromeRecur(end.next, start);
// Compare the start and end nodes.
let ans = right && start[0].data === end.data;
// Update the start node
start[0] = start[0].next;
return ans;
}
// Function to check whether the list is palindrome
function isPalindrome(head) {
// Set starting node to head
let start = [head];
// Recursively check the ll and return
return isPalindromeRecur(head, start);
}
// Linked list : 1->2->3->2->1
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
let result = isPalindrome(head);
if (result)
console.log("true");
else
console.log("false");
[Expected Approach] Using Iterative Method - O(n) Time and O(1) Space
The approach involves reversing the second half of the linked list starting from the middle. After reversing, traverse from the headof the list and the head of the reversed second half simultaneously, comparing the node values. If all corresponding nodes have equal values, the list is a palindrome.
Follow the steps below to solve the problem:
- Use two pointers , fast and slow to find the middle of the list. fast will move twosteps ahead and slowwill move one step ahead at a time.
- if list is odd, when fast->next is NULL , slow will point to the middle node.
- if list is even, when fast->next->next is NULLslow will point to the middlenode.
- Reverse the second half of the list starting from the middle.
- Check if the first half and the reversed second half are identical by comparingthe node values.
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int d) {
data = d;
next = nullptr;
}
};
// Function to reverse a linked list
Node* reverse(Node* head) {
Node* prev = nullptr;
Node* curr = head;
Node* next;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to check if two lists are identical
bool isIdentical(Node* n1, Node* n2) {
for (; n1 && n2; n1 = n1->next, n2 = n2->next)
if (n1->data != n2->data)
return 0;
// returning 1 if data at all nodes are equal.
return 1;
}
// Function to check whether the list is palindrome
bool isPalindrome(Node* head) {
if (!head || !head->next)
return true;
// Initialize slow and fast pointers
Node* slow = head;
Node* fast = head;
// Move slow to the middle of the list
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
// Split the list and reverse the second half
Node* head2 = reverse(slow->next);
slow->next = nullptr; // End the first half
// Check if the two halves are identical
bool ret = isIdentical(head, head2);
// Restore the original list
head2 = reverse(head2);
slow->next = head2;
return ret;
}
int main() {
// Linked list : 1->2->3->2-> 1
Node head(1);
head.next = new Node(2);
head.next->next = new Node(3);
head.next->next->next = new Node(2);
head.next->next->next->next = new Node(1);
bool result = isPalindrome(&head);
if (result)
cout << "true\n";
else
cout << "false\n";
return 0;
}
C
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
// Function to reverse a linked list
struct Node* reverse(struct Node* head) {
struct Node* prev = NULL;
struct Node* curr = head;
struct Node* next;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to check if two lists are identical
int isIdentical(struct Node* n1, struct Node* n2) {
for (; n1 && n2; n1 = n1->next, n2 = n2->next)
if (n1->data != n2->data)
return 0;
// returning 1 if data at all nodes are equal.
return 1;
}
// Function to check whether the list is palindrome
int isPalindrome(struct Node* head) {
if (!head || !head->next)
return 1;
struct Node *slow = head, *fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
struct Node* head2 = reverse(slow->next);
slow->next = NULL;
int ret = isIdentical(head, head2);
head2 = reverse(head2);
slow->next = head2;
return ret;
}
struct Node* createNode(int data) {
struct Node* newNode =
(struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
int main() {
// Linked list : 1->2->3->2->1
struct Node* head = createNode(1);
head->next = createNode(2);
head->next->next = createNode(3);
head->next->next->next = createNode(2);
head->next->next->next->next = createNode(1);
int result = isPalindrome(head);
if (result)
printf("true\n");
else
printf("false\n");
return 0;
}
Java
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
// Class to check if the linked list is palindrome or not
class GfG {
// Function to reverse a linked list
static Node reverseList(Node head) {
Node prev = null;
Node curr = head;
Node next;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to check if two lists are identical
static boolean isIdentical(Node n1, Node n2) {
while (n1 != null && n2 != null) {
if (n1.data != n2.data)
return false;
n1 = n1.next;
n2 = n2.next;
}
return true;
}
// Function to check whether the list is palindrome
static boolean isPalindrome(Node head) {
if (head == null || head.next == null)
return true;
Node slow = head, fast = head;
while (fast.next != null
&& fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
Node head2 = reverseList(slow.next);
slow.next = null;
boolean ret = isIdentical(head, head2);
head2 = reverseList(head2);
slow.next = head2;
return ret;
}
public static void main(String[] args) {
// Linked list : 1->2->3->2->1
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
boolean result = isPalindrome(head);
if (result)
System.out.println("true");
else
System.out.println("false");
}
}
Python
class Node:
def __init__(self, d):
self.data = d
self.next = None
# Function to reverse a linked list
def reverse(head):
prev = None
curr = head
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
return prev
# Function to check if two lists are identical
def isIdentical(n1, n2):
while n1 and n2:
if n1.data != n2.data:
return False
n1 = n1.next
n2 = n2.next
return True
# Function to check whether the list is palindrome
def isPalindrome(head):
if head is None or head.next is None:
return True
slow, fast = head, head
# Find the middle of the list
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
# Split the list and reverse the second half
head2 = reverse(slow.next)
slow.next = None
# Check if the two halves are identical
ret = isIdentical(head, head2)
# Restore the original list
head2 = reverse(head2)
slow.next = head2
return ret
if __name__ == "__main__":
# Linked list : 1->2->3->2->1
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(2)
head.next.next.next.next = Node(1)
result = isPalindrome(head)
if result:
print("true")
else:
print("false")
C#
using System;
class Node {
public int Data;
public Node Next;
public Node(int d) {
Data = d;
Next = null;
}
}
class GfG {
// Function to reverse a linked list
static Node reverseList(Node head) {
Node prev = null;
Node curr = head;
while (curr != null) {
Node next = curr.Next;
curr.Next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to check if two lists are identical
static bool isIdentical(Node n1, Node n2) {
while (n1 != null && n2 != null) {
if (n1.Data != n2.Data)
return false;
n1 = n1.Next;
n2 = n2.Next;
}
return true;
}
// Function to check whether the list is palindrome
static bool isPalindrome(Node head) {
if (head == null || head.Next == null) return true;
Node slow = head, fast = head;
// Find the middle of the list
while (fast.Next != null
&& fast.Next.Next != null) {
slow = slow.Next;
fast = fast.Next.Next;
}
// Split the list and reverse the second half
Node head2 = reverseList(slow.Next);
slow.Next = null;
// Check if the two halves are identical
bool ret = isIdentical(head, head2);
// Restore the original list
head2 = reverseList(head2);
slow.Next = head2;
return ret;
}
static void Main() {
// Linked list : 1->2->3->2->1
Node head = new Node(1);
head.Next = new Node(2);
head.Next.Next = new Node(3);
head.Next.Next.Next = new Node(2);
head.Next.Next.Next.Next = new Node(1);
bool result = isPalindrome(head);
Console.WriteLine(result ? "true" : "false");
}
}
JavaScript
class Node {
constructor(d) {
this.data = d;
this.next = null;
}
}
// Function to reverse a linked list
function reverseList(head) {
let prev = null;
let curr = head;
while (curr) {
let next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to check if two lists are identical
function isIdentical(n1, n2) {
while (n1 && n2) {
if (n1.data !== n2.data) {
return false;
}
n1 = n1.next;
n2 = n2.next;
}
return true;
}
// Function to check whether the list is palindrome
function isPalindrome(head) {
if (head === null || head.next === null) {
return true;
}
// Initialize slow and fast pointers
let slow = head;
let fast = head;
// Find the middle of the linked list
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
// Reverse the second half of the list
let head2 = reverseList(slow);
// Check if the two halves are identical
let ret = isIdentical(head, head2);
// Restore the original list
reverseList(head2);
return ret;
}
// Linked list : 1->2->3->2->1
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
let result = isPalindrome(head);
if (result) {
console.log("true");
} else {
console.log("false");
}
Explore
Basics & Prerequisites
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem