1,双指针解决
“回文串”是一个正读和反读都一样的字符串,也就是说他是左右两边对称的。验证一个字符串是否是回文串,最简单的一种方式就是使用两个指针,一个从前开始,一个从后开始,两个指针同时往中间走,如果他们指向的字符不一样,那么这个字符串肯定不是回文字符串,直接返回false即可,如果这两个指针相遇了,直接返回true。
但这题只需要判断字母和数字,因为字符串中可能含有其他字符,我们只需要跳过即可,画个图来看下
最后再来看下代码
public boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
//left是左指针,如果不是字母和数字要过滤掉
while (left < right && !Character.isLetterOrDigit(s.charAt(left)))
left++;
//right也一样,如果不是字母和数字也要过滤掉
while (left < right && !Character.isLetterOrDigit(s.charAt(right)))
right--;
//然后判断这两个字符是否相同,如果不相同直接返回false,这里是先把字符全部转化为小写
if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right)))
return false;
//如果left和right指向的字符忽略大小写相等的话,这两个指针要分别往中间移一步
left++;
right--;
}
//如果都比较完了,说明是回文串,返回true
return true;
}
我们还可以在比较之前字母全部转化为小写,这里改为for循环的方式,只不过是换汤不换药,原理还都是一样的,来看一下
public boolean isPalindrome(String s) {
//先转为小写
s = s.toLowerCase();
for (int i = 0, j = s.length() - 1; i < j; i++, j--) {
while (i < j && !Character.isLetterOrDigit(s.charAt(i)))
i++;
while (i < j && !Character.isLetterOrDigit(s.charAt(j)))
j--;
if (s.charAt(i) != s.charAt(j))
return false;
}
return true;
}
2,递归方式解决
上面代码还可以写成递归的方式,无论怎么变,核心思路还是没变,可以参考一下,代码如下
public boolean isPalindrome(String s) {
return isPalindromeHelper(s, 0, s.length() - 1);
}
public boolean isPalindromeHelper(String s, int left, int right) {
if (left >= right)
return true;
while (left < right && !Character.isLetterOrDigit(s.charAt(left)))
left++;
while (left < right && !Character.isLetterOrDigit(s.charAt(right)))
right--;
return Character.toLowerCase(s.charAt(left)) == Character.toLowerCase(s.charAt(right))
&& isPalindromeHelper(s, ++left, --right);
}