Given a singly linked list, determine if it is a palindrome.
Example:
linked list1 → 2 → 1 → Ø is a palindrome.
linked list1 → 2 → 3 → Ø is not a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
Solution 1
Convert the linked list to array, check if the array is a palindrome.
Time: O(n) extra space: O(n)
# Definition for singly-linked list.# class ListNode(object):# def __init__(self, x):# self.val = x# self.next = NoneclassSolution(object): def isPalindrome(self, head): """ :type head: ListNode :rtype: bool """ if not head: return True# convert linked list to array ret = [] node = head while node: ret.append(node.val) node = node.next return ret == ret[::-1]
Solution 2
Get the middle of the linked list using a slow pointer and a fast pointer
Reverse the second half of the linked list
Check if the first half and second half are identical
Time: O(n) Extra space: O(1)
# Definition for singly-linked list.# class ListNode(object):# def __init__(self, x):# self.val = x# self.next = NoneclassSolution(object):defisPalindrome(self,head):""" :type head: ListNode :rtype: bool """if head ==Noneor head.next ==None:returnTrue# find the middle of the linked list # using a slow pointer and a fast pointer slow = head fast = headwhile fast.next !=Noneand fast.next.next !=None: slow = slow.next fast = fast.next.next slow = slow.next# reverse the second half of the linked list slow = self.reverseList(slow)# check if the first half and second half are identicalwhile slow !=None:if head.val != slow.val:returnFalseelse: head = head.next slow = slow.nextreturnTrue# helper function to reverse a linked list defreverseList(self,next_node):""" :type next_node: ListNode :rtype: ListNode """ifnot next_node:return next_node prev_node =Nonewhile next_node: cur_node = next_node next_node = next_node.next cur_node.next = prev_node prev_node = cur_nodereturn prev_node