Valid Palindrome

Valid Palindrome#

Given a string, decide whether it reads the same forward and backward once you ignore case and consider only letters and digits. Punctuation and spaces do not count. Return true if it is a palindrome and false otherwise.

Example#

Input: s = "A man, a plan, a canal: Panama" Output: True, because the cleaned string “amanaplanacanalpanama” reads the same both ways.

Input: s = "race a car" Output: False.

Brute force#

Build a cleaned, lowercased string of only alphanumeric characters, then compare it with its reverse. This is correct but allocates a full extra copy of the string.

  • Time: O(n).
  • Space: O(n) for the cleaned copy.

Optimal approach#

Use two pointers, one at each end. Skip any character that is not alphanumeric. Compare the two characters after lowercasing them. If they ever differ, it is not a palindrome. Move the pointers toward each other until they cross. This checks the string in place without building a new one.

Python solution#

 1def is_palindrome(s):
 2    left, right = 0, len(s) - 1
 3    while left < right:
 4        while left < right and not s[left].isalnum():
 5            left += 1
 6        while left < right and not s[right].isalnum():
 7            right -= 1
 8        if s[left].lower() != s[right].lower():
 9            return False
10        left += 1
11        right -= 1
12    return True

Complexity#

  • Time: O(n), each character is visited at most once.
  • Space: O(1), only two index variables.

This problem is a textbook use of the two-pointer technique. Keep practicing with the 60-day challenge.