Apply two-pointer inward scanning to palindrome, reverse, and character filtering problems.
Published March 8, 2025
Two pointers on strings — typically one starting from each end and moving inward — elegantly solve palindrome checking, string reversal, and character filtering problems in O(n) time with O(1) space.
public boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
while (left < right && !Character.isLetterOrDigit(s.charAt(left))) left++;
while (left < right && !Character.isLetterOrDigit(s.charAt(right))) right--;
if (Character.toLowerCase(s.charAt(left)) !=
Character.toLowerCase(s.charAt(right))) return false;
left++;
right--;
}
return true;
}
public boolean validPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
// Try skipping left or right character
return isPalin(s, left + 1, right) || isPalin(s, left, right - 1);
}
left++;
right--;
}
return true;
}
private boolean isPalin(String s, int l, int r) {
while (l < r) {
if (s.charAt(l++) != s.charAt(r--)) return false;
}
return true;
}
public void reverseString(char[] s) {
int left = 0, right = s.length - 1;
while (left < right) {
char tmp = s[left];
s[left++] = s[right];
s[right--] = tmp;
}
}
public String reverseWords(String s) {
// Trim, split on whitespace, reverse array, join
String[] words = s.trim().split("\\s+");
int left = 0, right = words.length - 1;
while (left < right) {
String tmp = words[left];
words[left++] = words[right];
words[right--] = tmp;
}
return String.join(" ", words);
}
// Merge two sorted strings (like merge sort step)
public String mergeSorted(String a, String b) {
StringBuilder sb = new StringBuilder();
int i = 0, j = 0;
while (i < a.length() && j < b.length()) {
if (a.charAt(i) <= b.charAt(j)) sb.append(a.charAt(i++));
else sb.append(b.charAt(j++));
}
while (i < a.length()) sb.append(a.charAt(i++));
while (j < b.length()) sb.append(b.charAt(j++));
return sb.toString();
}
// Find smallest window in s containing all chars of t
public String minWindow(String s, String t) {
int[] need = new int[128];
for (char c : t.toCharArray()) need[c]++;
int required = t.length();
int left = 0, min = Integer.MAX_VALUE, start = 0;
for (int right = 0; right < s.length(); right++) {
if (need[s.charAt(right)]-- > 0) required--;
while (required == 0) { // window is valid
if (right - left + 1 < min) {
min = right - left + 1;
start = left;
}
if (need[s.charAt(left++)]++ == 0) required++;
}
}
return min == Integer.MAX_VALUE ? "" : s.substring(start, start + min);
}
validPalindrome is a classic follow-up to basic palindrome.