【题目】
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
来源:leetcode
链接:https://leetcode-cn.com/problems/valid-palindrome-ii/
【示例1】
输入: “aba”
输出: True
【示例2】
输入: “abca”
输出: True
解释: 你可以删除c字符。
【注意】
字符串只包含从 a-z 的小写字母。字符串的最大长度是50000
【代码及分析】耗时100ms
碰到不相等字符的时候,有两种删除方法,一个删除左边,一个删除右边,删除方式的不同可能导致结果不同。
class Solution {
public:
bool validPalindrome(string s) {
int low=0,l=0,high=s.size()-1,h=s.size()-1,cnt=0,c=0;
while(low<=high){
if(s[low]!=s[high]){
cnt++;
low++;
}else{
low++;
high--;
}
}
while(l<=h){
if(s[l]!=s[h]){
c++;
h--;
}else{
l++;
h--;
}
}
if(cnt<=1||c<=1)
return true;
return false;
}
};
【改进】改进之后的代码不仅变得简洁了,而且其复杂度也降低了一些,但是耗时仍比较多88ms,checkPalindrome是专门用来判断一个字符串是不是回文串的函数,如果是回文串则返回true,否则返回false,因为题目中说明允许删除一个字符,然后判断删除后的字符串是不是回文,所以我们需要对删除后的字符串进行判断,为了简化操作,在此将对字符串判断回文的功能单拎出来放在一个函数中,专门用来判断是不是回文,但是在碰到左右两边第一个不相等的字符的时候我们有两种删除方法,第一种是删除左边,第二种是删除右边,这部分就有点贪心算法的思想包含在内了
class Solution {
public:
bool checkPalindrome(const string& s, int low, int high) {
int i=low,j=high;
for (; i < j && s[i] == s[j]; ++i, --j);
return i>=j;
}
bool validPalindrome(string s) {
int low = 0, high = s.size() - 1;
while (low < high) {
if (s[low] == s[high]) {
++low;
--high;
}
else
return checkPalindrome(s, low, high - 1) || checkPalindrome(s, low + 1, high);
}
return true;
}
};