234. Palindrome Linked List

Overview
Check whether the value in the linked list is a palindrome or not.
Solution 1: List
Algorithm
-
Create a
nums
list to save thenode.val
in linked list nodes. -
Iterate through the linked list and append the
node.val
to thenums
list. -
Initialize
left
andright
two pointers to point to the list head and tail. -
Iterate through the
nums
list.
If the number at the left index is not equal to the number at right index,
it means it's not a palindrome linked list. Return false immediately. -
Return true because the left-hand side is equal to the reversed right-hand side.
Implement
class Solution: def isPalindrome(self, head: Optional[ListNode]) -> bool: nums: list[int] = [] while head is not None: nums.append(head.val) head = head.next left = 0 right = len(nums) - 1 while left < right: if nums[left] != nums[right]: return False left += 1 right -= 1 return True
Complexity Analysis
Time complexity: O(n)
Iterate though the linked list to save the node.va
l into nums
takes O(n).
Iterate through the nums
list will take half of the nums
list
if the numbers are all unique in half of the nums
, takes O(n/2).
The total time complexity can be simplified to O(n).
Space complexity: O(n)
We use an additional list to save the node.val
in the linked list, taking O(n) space.
Solution 2: Two Pointer
Algorithm
-
Initialize
slow
andfast
pointers and point on thehead
. Initializeprevious
as None. -
This iteration combines two techniques.
First, we use slow and fast pointer:
slow advances by one step, and fast advances by two steps.
When fast reaches the end, slow points to the middle node of the linked list.Another technique involves reversing the left half of the linked list,
using the algorithm discussed in question 206 yesterday.
previous
will point to the end of the left half and the left hand side had been reversed.
slow
will point on the start of the right half. -
If the length of the linked list is odd, we need to move slow one more time
so it points to the correct middle position. -
Iterate through
previous
andslow
to check if thenode.val
is equals or not.
Return false immediately if thenode.val
is not equal. -
Return true because the values of the previous nodes are equal to the values of the slow nodes.
Implement
class Solution: def isPalindrome(self, head: Optional[ListNode]) -> bool: slow = fast = head previous: Optional[ListNode] = None while fast and fast.next: fast = fast.next.next next = slow.next slow.next = previous previous, slow = slow, next if fast is not None: slow = slow.next while previous and slow: if previous.val != slow.val: return False previous = previous.next slow = slow.next return True
Complexity Analysis
Time complexity: O(n)
Iterating through half of the linked list to let slow
point to the middle and fast
point to the end takes O(n/2).
The pointer movements and reversing the left half of the linked list are all O(1) operations.
Iterating through previous
and slow
also takes half of the linked list, takeing O(n/2) time.
Therefore, the total time complexity is O(n).
Space complexity: O(1)
We create additional three pointers, which takes constraint space.
It won't grow up with the size of the input linked list.
So the total space complexity only takes O(1).
Solution 3: Stack
Algorithm
-
Create a
stack
list to save thenode.val
in linked list nodes. -
Iterate through the linked list and append the
node.val
to thestack
list. -
Iterate through the linked list again.
If the number isn't equal to the popped number from thestack
, it means it's not a palindrome linked list. Return false immediately. -
Return true because the values of the linked list is equal to the popped values from the
stack
(the reversed linked list).
Implement
class Solution: def isPalindrome(self, head: Optional[ListNode]) -> bool: stack: list[int] = [] current = head while current is not None: stack.append(current.val) current = current.next current = head while current is not None: if current.val != stack.pop(): return False current = current.next return True
Complexity Analysis
Time complexity: O(n)
Iterate though the linked list twice takes O(2n), which simplifies to O(n).
Space complexity: O(n)
We use an additional list to save the node.val
in the linked list, taking O(n) space.