双指针匹配 + 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;
    }