题目大意
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例1:
输入: "A man, a plan, a canal: Panama"
输出: true
示例2:
输入: "race a car"
输出: false
思路
这一题我首先想到的是用首尾指针,当不是字母或者数字时,指针相向移动。依次判断首尾是否对称。
代码一
自己写的第一版没有用Java的内置方法做。运行时间7ms。
public boolean isPalindrome(String s) {
if(s.length()==0) return true;
char[] str = s.toCharArray();
for(int i=0,j=str.length-1;i<j;++i,--j)
{
while(!isLetter(str[i]) && !isNumber(str[i]))
//注意这里的while可能出现死循环,留意正确的写法,记得边界要break
if(i==str.length-1) break;
else ++i;
while(!isLetter(str[j]) && !isNumber(str[j]))
if(j==0) break;
else --j;
if(lower(str[i])!=lower(str[j])) return false;
}
return true;
}
private char lower(char ch) {
if(ch>='A' && ch<='Z') return (char)(ch+32);
else if((ch>='a' && ch<='z')||(ch>='0' && ch<='9')) return ch;
else return ' ';
}
private boolean isLetter(char ch) {
return (ch>='A'&&ch<='Z') || (ch>='a' && ch<='z');
}
private boolean isNumber(char ch) {
return (ch>='0' && ch<='9');
}
注意:在这一版代码中,我写while循环时出现了死循环的问题,原因是因为当i == str.length-1的时候一直没有跳出循环。改正后加入了break的跳出,程序才调试好。
代码二
第二个版本是将一些判断字母/数字的函数换成了内置函数。代码更加地简洁。运行时间12ms。
public boolean isPalindrome(String s) {
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(Character.toLowerCase(s.charAt(i))!=Character.toLowerCase(s.charAt(j)))
return false;
}
return true;
}