Problem Statement
Given a string, check if it is a valid palindrome. A string is considered a palindrome if it reads the same forward and backward after converting all uppercase letters to lowercase and ignoring all non-alphanumeric characters.
Sample Test Case
Input: "A man, a plan, a canal: Panama"
Output: true
Approaches
Brute Force Approach
Idea
The brute force method involves reversing the string after removing all non-alphanumeric characters and converting everything to lowercase. If the reversed string is the same as the original cleaned string, it is a palindrome.
Steps
- Remove non-alphanumeric characters from the string.
- Convert all characters to lowercase.
- Reverse the cleaned string.
- Compare the reversed string with the cleaned string.
- Return
true if both are the same, otherwise return false.
Time Complexity
- O(n) for cleaning the string and O(n) for reversing, where
n is the length of the string.
- Total: O(n).
Space Complexity
- O(n) for storing the cleaned string and the reversed string.
- Total: O(n).
Example Code
Dry Run
For the input "A man, a plan, a canal: Panama":
- After cleaning:
"amanaplanacanalpanama"
- After reversing:
"amanaplanacanalpanama"
- Since both are the same, return
true.
Efficient Approach (Two-Pointer Technique)
Idea
The two-pointer approach compares characters from the beginning and end of the string, moving inward, while skipping non-alphanumeric characters. This approach avoids creating a new reversed string, improving space efficiency.
Steps
- Initialize two pointers:
left at the start and right at the end of the string.
- Move both pointers towards each other:
- Skip non-alphanumeric characters.
- Compare the characters at
left and right after converting them to lowercase.
- If all characters match, return
true. If any characters mismatch, return false.
Time Complexity
- O(n), where
n is the length of the string.
Space Complexity
- O(1) for using only pointers without additional space.
Example Code
Dry Run
For the input "A man, a plan, a canal: Panama":
left = 0, right = 29 → compare A with a → match.
- Continue inward, skipping non-alphanumeric characters and matching
m, a, n, and so on.
- Eventually, all characters match, so return
true.
Example Test Case
Test Case 1
Input: "race a car"
Output: false
Test Case 2
Input: " "
Output: true (Empty or whitespace strings are considered palindromes.)
Test Case 3
Input: "Able , was I saw eLba"
Output: true
Complexity Analysis
Brute Force Approach
- Time Complexity: O(n), where
n is the length of the string.
- Space Complexity: O(n), as additional space is used for the cleaned and reversed string.
Efficient (Two-Pointer) Approach
- Time Complexity: O(n), where
n is the length of the string.
- Space Complexity: O(1), as no additional space is used apart from the two pointers.
Conclusion
The brute force approach works but uses additional space to store the cleaned and reversed string. The two-pointer approach is more efficient in terms of space complexity, achieving O(1) space while still maintaining O(n) time complexity.