Palindrome Linked List easy
Problem Statement
Given the head
of a singly linked list, return true
if it is a palindrome, or false
otherwise.
Example 1:
Input: head = [1,2,2,1] Output: true
Example 2:
Input: head = [1,2] Output: false
Steps
-
Find the middle of the linked list: We use the slow and fast pointer technique. The slow pointer moves one step at a time, and the fast pointer moves two steps at a time. When the fast pointer reaches the end, the slow pointer will be at the middle.
-
Reverse the second half of the linked list: We reverse the linked list starting from the middle node.
-
Compare the first half and the reversed second half: We compare the nodes of the first half with the nodes of the reversed second half. If they are all the same, the linked list is a palindrome. Otherwise, it's not.
Explanation
The algorithm leverages the concept of slow and fast pointers to efficiently find the middle of the linked list in O(N) time. Reversing the second half is also an O(N) operation. Finally, comparing the two halves takes O(N/2) which simplifies to O(N). Therefore, the overall time complexity is O(N). Space complexity is O(1) because we're modifying the list in place rather than creating a new data structure to store the reversed second half (except for a few temporary variables).
Code
using System;
using System.Collections.Generic;
public class ListNode {
public int val;
public ListNode next;
public ListNode(int val = 0, ListNode next = null) {
this.val = val;
this.next = next;
}
}
public class Solution {
public bool IsPalindrome(ListNode head) {
// Handle empty or single-node lists
if (head == null || head.next == null) return true;
// Find the middle of the linked list
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// Reverse the second half of the linked list
ListNode prev = null;
ListNode curr = slow;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
// Compare the first half and the reversed second half
ListNode firstHalf = head;
ListNode secondHalf = prev;
while (secondHalf != null) {
if (firstHalf.val != secondHalf.val) return false;
firstHalf = firstHalf.next;
secondHalf = secondHalf.next;
}
return true;
}
}
Complexity
- Time Complexity: O(N), where N is the number of nodes in the linked list. This is because we traverse the list multiple times (finding the middle, reversing the second half, and comparing the halves).
- Space Complexity: O(1). The algorithm uses only a constant amount of extra space.