给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: "aba"输出: True
示例 2:
输入: "abca"
输出: True
解释: 你可以删除c字符。
注意:
- 字符串只包含从
a-z的小写字母。字符串的最大长度是50000。
1. 超时的做法:
题目问我们最多删除一个字符的情况下是否可以构成回文字符串,第一反应是逐个删除各个字符看剩下的字符串是否为回文串,但是这个时间复杂度是 O(N ^ 2) ,题目给出的字符串的长度最大为 50000 ,此做法会超时。
代码
class Solution {
public:
bool validPalindrome(string s) {
if (s.size() == 1) return true;
else if (s.size() == 0) return false;
if (isPalindrome(s)) {
return true;
}
else {
for (int i = 0; i < s.size(); i++) {
string tempStr = s;
tempStr.erase(tempStr.begin() + i);
if (isPalindrome(tempStr)) {
return true;
}
}
}
return false;
}
bool isPalindrome(string str) {
if (str.size() == 1) return true;
else if (str.size() == 0) return false;
int totalIndex = str.size() - 1;
for (int i = 0; i < totalIndex / 2 + 1; i++) {
if (str[i] != str[totalIndex - i]) {
return false;
}
}
return true;
}
};
2. 改进的做法
回文串的特点是左右对称。假如有两个指针从字符串的两端同时向中间走:如果遇到的元素相等,则该相等的元素是最终回文字符串的一部分;如果遇到的元素不等,则认为此时遇到了构建回文字符串的「障碍」,应当进行处理,处理方式见下文。
分析一下 例2:
输入: "abca" 输出: True 解释: 你可以删除c字符。如果左右指针从两端同时向中间走,那么: ``` 第一步: a b c a | | left right
第二步: a b c a | | left right
第一步,左右指针遇到的元素相等,继续向中间走;<br />第二步,左右指针遇到的元素不等,则必须进行处理:我们必须删除其中的一个字符,然后再判断 **剩余的所有字符** 是否是回文串。
删除 b: a c a
或者, 删除 c: a b a
即判断 `aca` 或者 `aba` 是否为回文字符串。
如果删除一个字符后,剩余的全部字符构成字符串 是回文字符串,那么就满足题意。
本方案的时间复杂度是: `O(N)` ;由于我判断是否回文使用了新建的字符串,所以空间复杂度是 `O(N)` 。
<a name="E8kZ9"></a>
#### 代码
```cpp
class Solution {
public:
bool validPalindrome(string s) {
if (s.size() == 1) return true;
else if (s.size() == 0) return false;
int totalIndex = s.size() - 1;
int left;
int right;
for (int i = 0; i < totalIndex / 2 + 1; i++) {
left = i;
right = totalIndex - i;
// 加入左边 != 右边
if (s[left] != s[right]) {
string strLeft = s;
string strRight = s;
strLeft.erase(strLeft.begin() + left);
strRight.erase(strRight.begin() + right);
if (isPalindrome(strLeft) || isPalindrome(strRight) ) {
return true;
}
else
return false;
}
}
return true;
}
bool isPalindrome(string str) {
if (str.size() == 1) return true;
else if (str.size() == 0) return false;
int totalIndex = str.size() - 1;
for (int i = 0; i < totalIndex / 2 + 1; i++) {
if (str[i] != str[totalIndex - i]) {
return false;
}
}
return true;
}
};
