這是兩道判斷字符串是否爲迴文的題目,先來看第一道:
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;
}