Two approaches to LeetCode Valid Palindrome โ brute force string rebuild O(n) and optimal two-pointer O(n) with O(1) space. Java and Python solutions with visual walkthrough.
LeetCode ยท #125
Valid Palindrome Solution
Given a string s, return true if it is a palindrome after converting to lowercase and removing all non-alphanumeric characters.
A phrase is a palindrome if, after converting all uppercase letters to lowercase and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.
Example 1
Input: s = "A man, a plan, a canal: Panama"Output:true// After cleanup: "amanaplanacanalpanama" โ reads same both ways
Example 2
Input: s = "race a car"Output:false// After cleanup: "raceacar" โ not a palindrome
Constraints
โข 1 โค s.length โค 2 ร 10โตโข s consists of printable ASCII characters
02
Section Two ยท Approach 1
Brute Force โ Build Clean String O(n)
Filter out non-alphanumeric characters, convert to lowercase, then check if the cleaned string equals its reverse. Simple but uses O(n) extra space for the cleaned copy.
Why we can do better
Problem: Building a new string and its reverse requires O(n) extra memory. Two pointers can compare characters in-place from both ends, skipping non-alphanumeric characters on the fly โ achieving O(1) space.
Java โ Clean + Reverse
classSolution {
publicbooleanisPalindrome(String s) {
StringBuilder clean = newStringBuilder();
for (char c : s.toCharArray())
if (Character.isLetterOrDigit(c))
clean.append(Character.toLowerCase(c));
return clean.toString().equals(clean.reverse().toString());
}
}
Python โ Clean + Reverse
classSolution:
defisPalindrome(self, s: str) -> bool:
clean = [c.lower() for c in s if c.isalnum()]
return clean == clean[::-1]
Metric
Value
Time
O(n) โ one pass to clean, one to reverse
Space
O(n) โ cleaned string + reversed copy
03
Section Three ยท Approach 2
Two Pointers โ O(n) time, O(1) space
Place one pointer at the start and one at the end. Move them inward, skipping non-alphanumeric characters. At each step, compare the two characters (case-insensitive). If they ever differ, return false. If the pointers cross, it's a palindrome.
๐ก Mental model: Two people hold opposite ends of a banner. They each walk inward, ignoring decorations (non-letters). At each step they compare their current letter โ if every pair matches, the banner reads the same from both sides.
Algorithm
Step 1: Set left = 0, right = s.length() - 1.
Step 2: While left < right: skip non-alphanumeric chars by advancing left / retreating right.
Step 3: Compare toLowerCase(s[left]) with toLowerCase(s[right]). If different โ false.
Step 4: Move both pointers inward: left++, right--.
Step 5: If pointers cross without mismatch โ true.
๐ฏ When to recognize this pattern:
Any problem comparing elements from both ends of a sequence โ palindrome checks, container problems, sorted-array pair finding.
The signal is symmetry: if the answer depends on matching the first with the last, second with second-to-last, etc., use converging two pointers.
04
Section Four ยท Trace
Visual Walkthrough
Trace through s = "A man, a plan, a canal: Panama":
Two Pointers โ converge from both ends, skip non-alphanumeric
05
Section Five ยท Implementation
Code โ Java & Python
Java โ Two Pointers
classSolution {
publicbooleanisPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
while (left < right && !Character.isLetterOrDigit(s.charAt(left)))
left++; // skip non-alphanumericwhile (left < right && !Character.isLetterOrDigit(s.charAt(right)))
right--; // skip non-alphanumericif (Character.toLowerCase(s.charAt(left)) !=
Character.toLowerCase(s.charAt(right)))
returnfalse; // mismatch
left++;
right--;
}
returntrue;
}
}
Python โ Two Pointers
classSolution:
defisPalindrome(self, s: str) -> bool:
left, right = 0, len(s) - 1while left < right:
while left < right and not s[left].isalnum():
left += 1while left < right and not s[right].isalnum():
right -= 1if s[left].lower() != s[right].lower():
returnFalse
left += 1
right -= 1returnTrue
06
Section Six ยท Analysis
Complexity Analysis
Approach
Time
Space
Trade-off
Clean + Reverse
O(n)
O(n)
Simple but builds two extra strings
Two Pointers โ optimal
O(n)
O(1)
In-place comparison, no extra strings
07
Section Seven ยท Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
Empty after cleanup
" " or ",.!"
All non-alphanumeric โ empty string is a palindrome โ true.
Single character
"a"
Trivially a palindrome.
Mixed case
"Aa"
Must compare case-insensitively โ true.
Numbers in string
"0P"
'0' and 'P' are both alphanumeric. '0' โ 'p' โ false.
All same character
"aaaa"
Every pair matches โ true.
โ Common Mistake: Forgetting the left < right guard inside the inner while-loops that skip non-alphanumeric characters. Without it, pointers can overshoot each other and cause an IndexOutOfBoundsException on strings like ".,,".