题目描述
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
示例:
输入: "aba"
输出: True
输入: "abca"
输出: True
解释: 你可以删除c字符。
注意:
- 字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。
题目链接: https://leetcode-cn.com/problems/valid-palindrome-ii/
思路1
首先判断原字符串是否是回文串,如果不是的话,每次删除一个字符后判断字符串是否是回文串。判断一个字符串是否是回文串的方法是:
- 设置两个指针 left=0, right=s.length()-1;
- 如果 left<=right,循环:
- 如果 s[left]!=s[right], return false;
- left++; right--;
- return true;
代码如下:
class Solution {
public:
bool validPalindrome(string s) {
if(s.empty()) return true;
if(isOk(s)) return true;
int n = s.length();
for(int i=0; i<n; i++){
string temp = s;
temp.erase(i, 1);
if(isOk(temp)) return true;
}
return false;
}
bool isOk(string s){
int left = 0;
int right = s.length()-1;
while(left<=right){
if(s[left]!=s[right]) return false;
left++;
right--;
}
return true;
}
};
// 超时
- 时间复杂度:O(n^2)
- 空间复杂度:O(n)
思路2
对思路 1 进行改进,首先设置两个指针 left=0,right=s.length()-1。将两个指针由两边向中间靠拢,如果 s[left]!=s[right],那么我们判断 s[left,...,right-1] 或者 s[left+1,...,right] 是否是回文串,如果这两个字符串有一个是回文串,则原字符串 s 就是回文串,否则 s 不是回文串。例如,s="bcaab"
,则c!=a
,所以两个字符串分别是 ca
和 aa
,因为 aa
是回文串,所以 s 也是回文串(去掉c
)。代码如下:
class Solution {
public:
bool validPalindrome(string s) {
if(s.empty()) return true;
if(isOk(s)) return true;
int n = s.length();
int left = 0, right = n-1;
while(left<=right){
if(s[left]!=s[right]){
int strLen = right-left;
/*string temp = s.substr(left, strLen+1);;
string temp1 = temp, temp2 = temp;
temp1 = temp1.erase(0, 1);
temp2.pop_back();*/
string temp1 = s.substr(left, strLen); // 不包含 left
string temp2 = s.substr(left+1, strLen); // 不包含 right
if(isOk(temp1) || isOk(temp2)) return true;
else return false;
}
left++;
right--;
}
return false;
}
/*判断 s 是否是回文串,是返回 true,否返回 false*/
bool isOk(string s){
int left = 0;
int right = s.length()-1;
while(left<=right){
if(s[left]!=s[right]) return false;
left++;
right--;
}
return true;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)