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. Given a string s, return true if it is a palindrome.
s = "A man, a plan, a canal: Panama"trues = "race a car"falsel = 0, r = n−1l < r: skip non-alphanumeric at l and rtoLowerCase(s[l]) vs toLowerCase(s[r]) — mismatch → falsel++, r--l ≥ r, all pairs matched → trueTwo-pointer palindrome check without building a cleaned string. Non-alphanumeric characters are skipped in-place — they never participate in comparison. Only mirror positions matter; case is normalized via lowercase. Any mismatch immediately proves the string is not a palindrome; if pointers cross, every alphanumeric char had a matching partner.
You could build a cleaned copy, reverse it, and compare. That works, but it uses O(n) extra space.
Use two pointers, left at the start and right at the end. If a pointer is on a space or a symbol, move it past. Otherwise compare the two characters in lowercase. If they differ, return false, otherwise move both pointers inward.
Two pointers from both ends check a palindrome in place. Skip what does not count, and compare the rest in lowercase.
Run the animation above on your own input, or watch the 1:22 video explanation of Valid Palindrome with a dry run and Java code.