题目
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: “A man, a plan, a canal: Panama”
输出: true
示例 2:
输入: “race a car”
输出: false
本题解答:双指针
本题双指针解法介绍:
- 一个从头开始一直找到字母/数字停止。
- 一个从尾部开始一直找到字母/数字停止。
- 忽视大小写比较二者相等性。
- 相等就继续,否则返回 false 。
判断 字符/数字 以及 统一字母大小写 可以有多种实现方式。
1. 使用Java库函数
使用了库函数:Character
注意:Character.toLowerCase(ch) 的返回值是 char,而不是Character对象。
代码
class Solution {
public boolean isPalindrome(String s) {
if(s == null || s.isEmpty()) return true;
int i = 0;
int j = s.length() - 1;
while(i < j) {
while(i < j && !Character.isLetterOrDigit(s.charAt(i))) i ++;
while(i < j && !Character.isLetterOrDigit(s.charAt(j))) j --;
if(Character.toLowerCase(s.charAt(i ++)) != Character.toLowerCase(s.charAt(j --))) return false;
}
return true;
}
}
结果
2. 自己实现字符控制
主要实现了字母大小写的统一。
两种方案:
- 转成大写:ch & 0b11011111 简写:ch & 0xDF
- 转成小写:ch | 0b00100000 简写:ch | 0x20
代码
class Solution {
public boolean isPalindrome(String s) {
if(s == null || s.isEmpty()) return true;
int i = 0;
int j = s.length() - 1;
while(i < j) {
while(i < j && !isLetterOrDigit(s.charAt(i))) i ++;
while(i < j && !isLetterOrDigit(s.charAt(j))) j --;
if((s.charAt(i ++) & 0xDF) != (s.charAt(j --) & 0xDF)) return false;
}
return true;
}
private boolean isLetterOrDigit(char ch) {
if(ch >= '0' && ch <= '9') return true;
if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) return true;
return false;
}
}