Learn DSA
Two Pointers
Sliding Window
Intervals
Stack
Binary Search
Heap
Depth-First Search
Breadth-First Search
Backtracking
Graphs
Dynamic Programming
Greedy Algorithms
Trie
Prefix Sum
Matrices
Palindrome Linked List
DESCRIPTION (credit 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.
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.
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
Complexity Analysis
Login to track your progress
Your account is free and you can post anonymously if you choose.