1题目:给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
https://leetcode-cn.com/problems/valid-palindrome-ii/description/
2 示例
示例 1:
输入: "aba"
输出: True
示例 2:
输入: "abca"
输出: True
解释: 你可以删除c字符。
注意:字符串只包含从 a-z 的小写字母。字符串的最大长度是50000
3 解答:双指针方法
1) 使用双指针方法判断回文字符串。设置一个左指针left(从左往右遍历),一个右指针right(从右往左遍历),这两个指针同时移动一个位置,如果对应的字符都相等,则字符串才是回文字符串。
2)在两个指针遍历的过程中,如果存在两个指针对应的字符不相等,则试着删除一个字符(这里容易出错),再判断之后的字符串是否是回文。
注意:在判断是否为回文字符串时,我们不需要判断整个字符串,因为左指针左边和右指针右边的字符之前已经判断过具有对称性质,所以只需要判断中间的子字符串即可。
4 代码
function isPalindrome(str, leftChild, rightChild) {
//判断换一个字符串是否是回文字符串
while (leftChild <= rightChild){
if(str[leftChild] === str[rightChild]){
leftChild++;
rightChild--;
}else {
return false;
}
}
return true;
}
var validPalindrome = function(s) {
var left = 0; //左指针,从左往右遍历
var right = s.length - 1; //右指针,从右往左遍历
while(left <= right){
if(s[left] === s[right]){
left++;
right--;
}else{
//此处容易出错
//记得此处必须是并列
return isPalindrome(s, left + 1, right) || isPalindrome(s, left, right - 1);
}
}
return true;
};
5错误示例代码
错误示例:
"aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga"
这么长,我当时查错误的时候,晕死了。后面让left左往右遍历,right从右往左遍历,相同的字符则删除简化,最后得出了原因。不用看上面这个例子,看下面简化的“acuppucua”。
function isPalindrome(str ,strLeft, strRight) {
while (strLeft <= strRight){
if(str[strLeft] === str[strRight]){
strLeft++;
strRight--;
}else {
return false;
}
}
return true;
}
var validPalindrome = function(s) {
var left = 0;
var right = s.length-1;
while(left < right){
if(s[left] === s[right]){
left++;
right--;
}else{
//错误原因,判断条件出错。看似删除左边字符或者删除右边字符能同时判断,但是事实上并不是。
//请看示例“acuppucua”,当left指向“c”,而right指向“u”时,符合条件1,即删除左指针+1对应的字符,然后执行条件1的代码,发现该子字符串并不是回文,返回了false。
//但是请看当删除右边指针-1的字符时,剩下的字符形成回文。注意多个if语句中,而且每个if语句下面有return语句,则只能选一个进行,而不是都能执行这些if语句
if(s[left + 1] === s[right]){ //条件1
return isPalindrome(s, left+1, right);
}
if(s[left] === s[right - 1]){ //条件2
return isPalindrome(s, left, right - 1);
}
}
}
return true;
};