这是两道判断字符串是否为回文的题目,先来看第一道:
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.
Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.
For the purpose of this problem, we define empty string as valid palindrome.
本题是对于一个字符串(可能含有各种符号)判断其中的字母和数字是否可以构成回文字符串,不考虑大小写之间的区别。题目很简单,使用java内置的函数即可判断一个字符是否为字母或者数字,如果不是的话接着判断下一个字符即可:
//45%
public static boolean isPalindrome(String s) {
s = s.toLowerCase();
char [] res = s.toCharArray();
int i=0, j=res.length-1;
while(i <= j){
//不是字母或者数字则遍历下一个
while(i<=j && !Character.isLetterOrDigit(res[i])) i++;
while(i<=j && !Character.isLetterOrDigit(res[j])) j--;
if(res[i] != res[j])
return false;
else{
i++;
j--;
}
}
return true;
}
此外,我们还可以使用正则表达式的方法来解决,但是效率比较低只能击败8%的用户:
//8.8%
public boolean isPalindrome1(String s) {
String actual = s.replaceAll("[^A-Za-z0-9]", "").toLowerCase();
String rev = new StringBuffer(actual).reverse().toString();
return actual.equals(rev);
}
然后还在discuss中看到了一个效率很高的代码,思想都是一样的,不过这里作者使用数组来实现判断一个字符是否为字母或者数字,效率很高,可以击败99。5%的用户,代码如下所示:
//99.5%
private static final char[]charMap = new char[256];
static{
for(int i=0;i<10;i++){
charMap[i+'0'] = (char)(1+i); // numeric
}
for(int i=0;i<26;i++){
charMap[i+'a'] = charMap[i+'A'] = (char)(11+i); //alphabetic, ignore cases
}
}
public boolean isPalindrome2(String s) {
char[]pChars = s.toCharArray();
int start = 0,end=pChars.length-1;
char cS,cE;
while(start<end){
cS = charMap[pChars[start]];
cE = charMap[pChars[end]];
//如果不是字母或者数字则返回0
if(cS!=0 && cE!=0){
if(cS!=cE)return false;
start++;
end--;
}else{
if(cS==0)start++;
if(cE==0)end--;
}
}
return true;
}
接下来看第二道题目:
Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.
Example 1:
Input: "aba"
Output: True
Example 2:
Input: "abca"
Output: True
Explanation: You could delete the character 'c'.
Note:
The string will only contain lowercase characters a-z. The maximum length of the string is 50000.
本题是看资格只有小写字母的字符串中去掉任意一个字符是否可以成为回文字符串,方法也比较简单,就是逐个判断,当出现不想等到时候就尝试删除两个中的一个,然后在判断剩下的字符串是否可以形成回文字符串即可。代码如此下所示:
public boolean validPalindrome1(String s) {
char[] res = s.toCharArray();
int l = -1, r = s.length();
while (++l < --r)
if (res[l] != res[r]) return isPalindromic(res, l, r+1) || isPalindromic(res, l-1, r);
return true;
}
public boolean isPalindromic(char[] res, int l, int r) {
while (++l < --r)
if (res[l] != res[r]) return false;
return true;
}