learn deep. ship safe.Practice testsFollow ByteMunSubscribe

easyStringsTwo pointers

Palindrome Sentence

Check whether a sentence reads the same forwards and backwards once you ignore case, spaces and punctuation. Practises the two-pointer technique on strings.

By Tests checked by DeepakJavaScript or Python

Given a string s, return true if it is a palindrome after converting letters to lowercase and removing every character that isn't a letter or a digit. Otherwise return false.

Only the ASCII letters a-z, A-Z and digits 0-9 count.

Examples

Example 1

Input: s = "Never odd or even."
Output: true
Why: "neveroddoreven" reads the same both ways

Example 2

Input: s = "Node, not done"
Output: false

Constraints

  • 0 <= s.length <= 2 * 10^5
  • s contains printable ASCII characters

Hints

Hint 1

Building a cleaned copy of the string works. Can you check it without building a copy?

Hint 2

Use one pointer from each end; skip characters that don't count, compare the rest in lowercase.

Solution

Show the solution (try it yourself first)

Approach: two pointers

Start one pointer at each end of the string. Move each pointer past characters that aren't letters or digits, then compare the two characters in lowercase. If they differ, it isn't a palindrome; otherwise move both pointers inward. This avoids building a cleaned copy, so it uses constant extra space. Watch the trap in "0P": digits count too, and "0" is not "p". A string with no letters or digits at all, like ".,!", is a palindrome because there is nothing to mismatch.

function isPalindromeSentence(s) {
  const ok = (c) => /[a-z0-9]/i.test(c);
  let i = 0, j = s.length - 1;
  while (i < j) {
    if (!ok(s[i])) { i++; continue; }
    if (!ok(s[j])) { j--; continue; }
    if (s[i].toLowerCase() !== s[j].toLowerCase()) return false;
    i++; j--;
  }
  return true;
}

Complexity

Time O(n), each character is visited at most once. Space O(1). The clean-then-reverse version is shorter but uses O(n) extra memory.

Case 1Input: "Never odd or even."Expected: true
Case 2Input: "Node, not done"Expected: false

Run checks these 2 samples. Submit checks all 8 tests, including hidden ones.

  1. Balanced BracketsStack · Strings
    easy
  2. Longest Substring Without RepeatsStrings · Sliding window · Hash map
    medium
  3. Group AnagramsStrings · Hash map · Sorting
    medium
  4. Pair with Target SumArrays · Hash map
    easy