双指针匹配 + ASCII解法
- 遍历字符数组的循环条件: while(left < right)
- left和right最开始分别指向字符串的首部和尾部,通过字符串转换为字符数组,遍历匹配left和right指向的数组元素是否相等
- 字符串中只考虑数字和大小写字母,则遍历过程中,如果遇到其他字符,则直接使左右指针指向下一个位置(left++,right--)
- 当匹配字符中是字母,但大小写不一致时进行匹配,通过大小写字母在ASCII里的值+/-32来实现它的大小写转换
- 字符串字符匹配中,存在相同字符大小写情况,可以枚举为4种情况:
- array[left](小写) array[right](大写) ==>> array[left](小写) - 32 = array[right](大写)
- array[left](大写) array[right](小写) ==>> array[left](大写) + 32 = array[right](小写)
- array[left](小写) array[right](小写) ==>> array[left] = array[right]
- array[left](大写) array[right](大写) ==>> array[left] = array[right]
- 时间复杂度: O(n)
- 空间复杂度: O(1)
代码
public boolean isPalindrome(String s) {
if(s == null) return false;
if(s != null && s.length() == 0) return true;
char[] array = s.toCharArray();
int left = 0;
int right = s.length() - 1;
while(left < right){
//非英文字母和数字情况,left指针右移
while (left < right && !((array[left] >= 'a' && array[left] <= 'z') || (array[left] >= 'A' && array[left] <= 'Z') || (array[left] >= '0' && array[left] <= '9'))) {
left++;
}
//非英文字母和数字情况,right指针左移
while (left < right && !((array[right] >= 'a' && array[right] <= 'z') || (array[right] >= 'A' && array[right] <= 'Z') || (array[right] >= '0' && array[right] <= '9'))) {
right--;
}
//不匹配
//字母通过ASCII的大小写值的差值32来匹配大小写相同字母的比较,数字不需要
//一个字母的ASCII值 +/- 32 一定有一个值是当前字母的大写或小写
if (!(
((array[left] >= 'a' && array[left] <= 'z' || array[left] >= 'A' && array[left] <= 'Z') &&
(array[right] >= 'a' && array[right] <= 'z' || array[right] >= 'A' && array[right] <= 'Z') &&
(array[left] - 32 == array[right] || array[left] + 32 == array[right]))
|| array[left] == array[right])) {
return false;
}
//left,right指针移动到下一位
left++;
right--;
}
//完全匹配,是回文串
return true;
}