A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.
Given a string s
, return true
if it is a palindrome, or false
otherwise.
Example 1:
Input: s = "A man, a plan, a canal: Panama" Output: true Explanation: "amanaplanacanalpanama" is a palindrome.
Example 2:
Input: s = "race a car" Output: false Explanation: "raceacar" is not a palindrome.
Example 3:
Input: s = " " Output: true Explanation: s is an empty string "" after removing non-alphanumeric characters. Since an empty string reads the same forward and backward, it is a palindrome.
Constraints:
1 <= s.length <= 2 * 105
s
consists only of printable ASCII characters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach for checking if something is a palindrome means we'll examine every possible pairing of characters. We'll look at the original string and see if it reads the same forwards and backward, ignoring non-letter stuff. This involves a direct, character-by-character comparison.
Here's how the algorithm would work step-by-step:
def is_valid_palindrome(input_string):
processed_string = ''.join(character.lower() for character in input_string if character.isalnum())
left_index = 0
right_index = len(processed_string) - 1
# Compare characters from both ends until indices meet
while left_index < right_index:
if processed_string[left_index] != processed_string[right_index]:
return False
left_index += 1
right_index -= 1
return True
The goal is to check if a sentence reads the same forwards and backward, ignoring unimportant details like capitalization and punctuation. Instead of comparing the entire sentence directly, we can focus on comparing only the important parts from both ends moving inward. This avoids unnecessary comparisons and speeds up the process.
Here's how the algorithm would work step-by-step:
def is_valid_palindrome(input_string):
cleaned_string = ''.join(character.lower() for character in input_string if character.isalnum())
starting_index = 0
ending_index = len(cleaned_string) - 1
# Compare characters from both ends moving inward.
while starting_index < ending_index:
if cleaned_string[starting_index] != cleaned_string[ending_index]:
return False
starting_index += 1
ending_index -= 1
# If the loop finishes, it's a valid palindrome.
return True
Case | How to Handle |
---|---|
Empty string | The problem states an empty string is a valid palindrome, so return true. |
Null string | Handle a null string input, typically by returning true (treating it as empty) or throwing an IllegalArgumentException based on requirements. |
String with only non-alphanumeric characters | After filtering, the string becomes empty, which should be handled as a valid palindrome returning true. |
String with a single alphanumeric character | A single character is always a palindrome, return true. |
String with two identical alphanumeric characters | This is a valid palindrome, return true. |
String with two different alphanumeric characters | This is not a valid palindrome, return false. |
String with mixed case alphanumeric characters (e.g., 'Racecar') | Convert the string to lowercase before comparison to handle case-insensitivity. |
String with very long length approaching system limits | Ensure the solution has optimal time complexity O(n) and doesn't cause stack overflow with recursive calls; iterative two-pointer is preferred. |