Given a string, determine whether it is a palindrome after converting uppercase to lowercase and ignoring all non-alphanumeric characters. The machine must compare characters that may be separated by arbitrary punctuation, whitespace, and case differences.
The key insight: a palindrome reads the same from both ends, so two pointers — one from the left, one from the right — can compare inward. The trick is the skip: each pointer must advance past non-alphanumeric characters independently before comparing, because the ignored characters are not mirrored. Only compare when both pointers rest on real characters.
Approach:
- Put
leftat index 0 andrightat the last index. - Advance each pointer past non-alphanumerics; compare lowercased characters.
- Any mismatch returns
False; pointers crossing means all pairs matched.
def is_palindrome(s):
left, right = 0, len(s) - 1
while left < right:
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
if s[left].lower() != s[right].lower():
return False
left, right = left + 1, right - 1
return TrueTime: O(n). Space: O(1) — no cleaned copy is built.
Trickiest edge case: all-ignored input like " " or ".," — the inner skip loops must be bounded by left < right or they run off the end of the string.