Linked List
Palindrome Linked List
DESCRIPTION (inspired by Leetcode.com)
Given a reference of type ListNode which is the head of a singly linked list, write a function to determine if the linked list is a palindrome.
# Definition of a ListNode class ListNode: def __init__(self, value=0, next=None): self.value = value self.next = next
A linked list is a palindrome if the values of the nodes are the same when read from left-to-right and right-to-left. An empty list is considered a palindrome.
Example 1:
Output:
True
left-to-right: 5 -> 4 -> 3 -> 4 -> 5 right-to-left: 5 -> 4 -> 3 -> 4 -> 5
Example 2:
Output:
False
left-to-right: 5 -> 4 -> 3 right-to-left: 3 -> 4 -> 5
Solutions
1. Convert to List: Compare Reverse
def isPalindrome(head):# convert linked list to listvals = []current_node = headwhile current_node:vals.append(current_node.val)current_node = current_node.next# compare list with its reversereturn vals == vals[::-1]
palindrome linked list
0 / 7
2. Convert to List: Two-Pointer Technique
def isPalindrome(head):# convert linked list to listvals = []current = headwhile current:vals.append(current.val)current = current.nextleft, right = 0, len(vals) - 1while left < right:if vals[left] != vals[right]:return Falseleft, right = left + 1, right - 1return True
palindrome linked list
0 / 10
3. Optimal Solution: Reverse Second Half
Step 1: Find the Middle of the Linked List
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
initialize pointers
0 / 2
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
initialize pointers
0 / 2
Step 2: Reverse second half of list
- save the next node in the iteration by setting next_ = curr.next
- reverse the pointer by setting curr.next = prev
- move pointers for the next iteration by set curr = next_ and prev = curr
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
find middle node
0 / 10
Step 3: Check for Palindrome
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
curr = next_, prev = curr
0 / 5
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
curr = next_, prev = curr
0 / 3
- Find the middle of the linked list using the fast and slow pointers technique.
- Reverse the direction of the nodes in the second half of the linked list.
- Use two-pointers to check for a palindrome by comparing the values of the nodes in the first half of the list with the reversed second half of the list.
Implementation
def is_palindrome(head):# Find middle of the linked list using fast and slow pointersslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# Reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # Save next nodecurr.next = prev # Reverse pointerprev = curr # Move pointerscurr = next_# Check palindrome by comparing halvesleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
Code
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
palindrome linked list
0 / 18
Edge Cases
Empty List
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
palindrome linked list
0 / 4
Single Node
- fast.next is None, so the first while loop to find the middle node doesn't execute.
- Reversing the second half of the list has no effect because there is only one node.
- The palindrome check returns True because a single node is a palindrome.
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
palindrome linked list
0 / 8
Two Nodes (Palindrome)
- The first while loop sets the slow pointer to the second node.
- Reversing the second half of the list has no effect slow.next is None already.
- The palindrome check compares the values of the two nodes and returns True if they are equal.
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
palindrome linked list
0 / 9
Two Nodes (Not Palindrome)
def is_palindrome(head):# find middle node of the listslow = fast = headwhile fast and fast.next:fast = fast.next.nextslow = slow.next# reverse second half of the listcurr, prev = slow, Nonewhile curr:next_ = curr.next # save next nodecurr.next = prev # reverse pointerprev = curr # move pointerscurr = next_# Check palindromeleft, right = head, prevwhile right:if left.val != right.val:return Falseleft = left.nextright = right.nextreturn True
palindrome linked list
0 / 8
Test Your Knowledge
Login to take the complexity quiz and track your progress
Complexity Analysis
Time Complexity: O(n) where n is the number of nodes in the linked list. We iterate through the linked list three times: once to find the middle node, once to reverse the second half of the list, and once to check for palindrome. All of these operations are O(n).
Space Complexity: O(1) The solution doesn't allocate any additional space other than a few pointers. Since the number of pointers stays fixed regardless of the number of nodes in the linked list, the space complexity is O(1).
Mark as read
Your account is free and you can post anonymously if you choose.