Input: "aba"
Output: True
Input: "abca"
Output: True
Explanation: You could delete the character 'c'.
这题,一看,bruteforce的话,可以一个一个试。然后因为parlindrom所以就想到对撞型双指针。一开始,中间那段,用了if else。譬如,left + 1 == right,就 --,left == right - 1,就++。因为是if else,所以不能两者兼得,而实际情况是,两个只要一个ok就return true。所以最后换成了递归。这里也只会递归一次,因为用了deletedOnce来控制。
public boolean validPalindrome(String s) {
if (s == null || s.length() == 0) {
return false;
}
return parHelper(s, false);
}
private boolean parHelper(String s, boolean deletedOnce) {
int left = 0;
int right = s.length() - 1;
while (left < right) {
char leftChar = s.charAt(left);
char rightChar = s.charAt(right);
if (leftChar != rightChar) {
if (!deletedOnce) {
if (leftChar == s.charAt(right - 1) || rightChar == s.charAt(left + 1)) {
return parHelper(s.substring(left, right), true)
|| parHelper(s.substring(left + 1, right + 1), true);
} else {
return false;
}
} else {
return false;
}
} else {
left++;
right--;
}
}
return true;
}
// 容易懂的方法
public boolean validPalindrome(String s) {
if (s == null || s.isEmpty()) {
return true;
}
int left = 0;
int right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return isPalindromeRange(s, left + 1, right) ||
isPalindromeRange(s, left, right - 1);
}
left++;
right--;
}
return true;
}
private boolean isPalindromeRange(String s, int left, int right) {
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
// 这个参考答案的下标比较复杂,所以还是写比较笨的方法吧
public boolean isPalindromeRange(String s, int i, int j) {
for (int k = i; k <= i + (j - i) / 2; k++) {
if (s.charAt(k) != s.charAt(j - k + i)) return false;
}
return true;
}
public boolean validPalindrome(String s) {
for (int i = 0; i < s.length() / 2; i++) {
if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
int j = s.length() - 1 - i;
return (isPalindromeRange(s, i+1, j) ||
isPalindromeRange(s, i, j-1));
}
}
return true;
}