Python Program To Check If A Singly Linked List Is Palindrome
Last Updated :
22 Feb, 2023
Given a singly linked list of characters, write a function that returns true if the given list is a palindrome, else false.
METHOD 1 (Use a 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 the stack and compare data of popped node with the currently visited node.
- If all nodes matched, then return true, else false.
Below image is a dry run of the above approach:
Below is the implementation of the above approach :
Python3
class Node:
def __init__( self , data):
self .data = data
self .ptr = None
def ispalindrome(head):
slow = head
stack = []
ispalin = True
while slow ! = None :
stack.append(slow.data)
slow = slow.ptr
while head ! = None :
i = stack.pop()
if head.data = = i:
ispalin = True
else :
ispalin = False
break
head = head.ptr
return ispalin
one = Node( 1 )
two = Node( 2 )
three = Node( 3 )
four = Node( 4 )
five = Node( 3 )
six = Node( 2 )
seven = Node( 1 )
one.ptr = two
two.ptr = three
three.ptr = four
four.ptr = five
five.ptr = six
six.ptr = seven
seven.ptr = None
result = ispalindrome(one)
print ( "isPalindrome:" , result)
|
Output:
isPalindrome: true
Time complexity: O(n), where n represents the length of the given linked list.
Auxiliary Space: O(n), for using a stack, where n represents the length of the given linked list.
METHOD 2 (By reversing the list):
This method takes O(n) time and O(1) extra space.
1) Get the middle of the linked list.
2) Reverse the second half of the linked list.
3) Check if the first half and second half are identical.
4) Construct the original linked list by reversing the second half again and attaching it back to the first half
To divide the list into two halves, method 2 of this post is used.
When a number of nodes are even, the first and second half contain exactly half nodes. The challenging thing in this method is to handle the case when the number of nodes is odd. We don’t want the middle node as part of the lists as we are going to compare them for equality. For odd cases, we use a separate variable ‘midnode’.
Python3
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" )
else :
print ( "Not Palindrome" )
print ()
|
Output:
a->NULL
Is Palindrome
b->a->NULL
Not Palindrome
a->b->a->NULL
Is Palindrome
c->a->b->a->NULL
Not Palindrome
a->c->a->b->a->NULL
Not Palindrome
b->a->c->a->b->a->NULL
Not Palindrome
a->b->a->c->a->b->a->NULL
Is Palindrome
Time Complexity: O(n)
Auxiliary Space: O(1)
Please refer complete article on Function to check if a singly linked list is palindrome for more details!
Share your thoughts in the comments
Please Login to comment...