题目描述
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: “aba”
输出: True
示例 2:
输入: “abca”
输出: True
解释: 你可以删除c字符。
注意:
字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。
分析
本题的关键是可以删去一个字符,利用双指针,一个指针从头向尾扫描,一个指针从尾向头扫描。指针扫描过的元素一定是对称的。当两指针指向的元素不同时,可以行使删除一个元素的权力,分别判断删去头元素和尾元素的子串是否是回文字符串。若至少有一个子串是回文字符串,则s为回文字符串;若两个子串都不是回文字符串,则s不是回文字符串。
代码
public class ValidPalindrome {
public boolean validPalindrome(String s) {
int p = 0, q = s.length()-1;
while(p < q) {
if(s.charAt(p) == s.charAt(q)) {
p++;
q--;
}
else { //两指针指向的元素不相同时,分别检查去掉头和尾的子串是否为回文字符串
return isPalindrome(s, p, q-1) || isPalindrome(s, p+1, q);
}
}
return true;
}
/**
* 判断子串是否为回文字符串
* @param s
* @param low
* @param high
* @return
*/
private boolean isPalindrome(String s, int low, int high) {
while(low < high) {
if(s.charAt(low) == s.charAt(high)) {
low++;
high--;
}
else
return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
ValidPalindrome vp = new ValidPalindrome();
if(vp.validPalindrome(str))
System.out.println("True");
else
System.out.println("False");
}
}
代码也可以更简洁,isPalindrome方法的while主体可写为以下这样,但写成这样运行时间大大加长。
if(s.charAt(low++) != s.charAt(high--)) {
return false;
}