Check If a Sentence Reads the Same Ignoring Case and Symbols
Solve this Problems that may contain letters, digits, spaces, and punctuation, determine whether it reads the same forwards and backwards once you ignore case and skip every character that isn't a letter or a digit.
Try to solve it by scanning inward from both ends of the original string at once, rather than building a cleaned copy first — that gets you to O(1) extra space.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ s.length ≤ 200 - ◆
s consists of printable ASCII characters — letters, digits, spaces, and punctuation
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public boolean isSentencePalindrome(String s) { |
| 3 | int left = 0, right = s.length() - 1; |
| 4 | while (left < right) { |
| 5 | while (left < right && !Character.isLetterOrDigit(s.charAt(left))) left++; |
| 6 | while (left < right && !Character.isLetterOrDigit(s.charAt(right))) right--; |
| 7 | if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) return false; |
| 8 | left++; |
| 9 | right--; |
| 10 | } |
| 11 | return true; |
| 12 | } |
| 13 | } |
| 14 |
018Set left to index 0 and right to the last index, 18. We'll move them toward each other, skipping anything that isn't a letter or digit.
Approach & Solutions
Brute Force — Build a Cleaned Copy
BruteWalk the string once, keeping only letters and digits and lowercasing each one as you go, to build a cleaned copy. Then compare that copy to its own reverse. Simple to reason about, but it needs a second string the same size as the cleaned input just to check the answer.
O(n)O(n)1class Solution {
2 public boolean isSentencePalindrome(String s) {
3 StringBuilder cleaned = new StringBuilder();
4 for (char c : s.toCharArray()) {
5 if (Character.isLetterOrDigit(c)) cleaned.append(Character.toLowerCase(c));
6 }
7 String forward = cleaned.toString();
8 String backward = cleaned.reverse().toString();
9 return forward.equals(backward);
10 }
11}Optimal — Two Pointers, Skip in Place
OptimalSkip building a second string at all. Walk two pointers inward from both ends of the original string. At each step, slide either pointer past any character that isn't a letter or digit, then compare the lowercased characters the pointers land on. Any mismatch means it's not a palindrome; if the pointers meet or cross with no mismatch found, it is.
O(n)O(1) extra1class Solution {
2 public boolean isSentencePalindrome(String s) {
3 int left = 0, right = s.length() - 1;
4 while (left < right) {
5 while (left < right && !Character.isLetterOrDigit(s.charAt(left))) left++;
6 while (left < right && !Character.isLetterOrDigit(s.charAt(right))) right--;
7 if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) return false;
8 left++;
9 right--;
10 }
11 return true;
12 }
13}