Problem
Given the head
of a singly linked list, return true
if it is a palindrome or false
otherwise.
Examples
Example 1:
Input: head = [1,2,2,1]
Output: true
head = 1 -> 2 -> 2 -> 1
Example 2:
Input: head = [1,2]
Output: true
head = 1 -> 2
Solution
Method 1 - Using Array to Store Linked List
We can store values from linked list in an array. Then the problem becomes - Check if given array is Palindrome OR Not
Code
Java
public boolean isPalindrome(ListNode head) {
if(head == null)
return true;
List<Integer> arrList = new ArrayList<>();
ListNode p = head;
while(p != null){
arrList.add(p.val);
p = p.next;
}
return isPalindrome(
arrList.stream().mapToInt(i -> i).toArray());
}
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(n)
Method 2 - Create new reversed list and compare
We can create a new list in reversed order and then compare each node. Here is the Reverse Linked List Problem.
Code
Java
public boolean isPalindrome(ListNode head) {
if(head == null)
return true;
ListNode p = head;
ListNode prev = new ListNode(head.val);
while(p.next != null){
ListNode temp = new ListNode(p.next.val);
temp.next = prev;
prev = temp;
p = p.next;
}
ListNode p1 = head;
ListNode p2 = prev;
while(p1!=null){
if(p1.val != p2.val){
return false;}
p1 = p1.next;
p2 = p2.next;
}
return true;
}
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(n)
Method 3 - Break and Reverse Second Half 🏆
We can use a fast and slow pointer to get the center of the list, then reverse the second list and compare two sublists.
- Get the middle of the linked list
- Reverse the second half of the linked list.
- Compare the first half and second half.
- Construct the original linked list by reversing the second half again and attaching it back to the first half.
Downside of the approach is we are changing our DS.
Code
Java
public boolean isPalindrome(ListNode head) {
if(head == null || head.next==null)
return true;
//find list middle = slow pointer
ListNode fast = head;
ListNode slow = head;
while(fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
}
//reverse second part of the list
ListNode prev = null;
while(slow!=null){
ListNode nxt = slow.next;
slow.next = prev;
prev = slow;
slow = nxt;
}
// Check palindrome
ListNode left = head, right = prev;
// we are using right as for odd numbered list
// right side will be smaller
while(right!=null){
if(left.val != right.val)
return false;
left = left.next;
right = right.next;
}
return true;
}
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)
Method 4 - Recursive 🏆
Code
Java
public class Solution {
ListNode left;
public boolean isPalindrome(ListNode head) {
left = head;
boolean result = helper(head);
return result;
}
public boolean helper(ListNode right){
//stop recursion
if (right == null)
return true;
//if sub-list is not palindrome, return false
boolean x = helper(right.next);
if (!x)
return false;
//current left and right
boolean y = (left.val == right.val);
//move left to next
left = left.next;
return y;
}
}
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)