思路:
1、双指针遍历,看字符是否对应相等
函数代码:
class Solution {
private:
bool isrestPalindrome(string s,int i,int j){
while(i<j){
if(s[i++]!=s[j--]) return false; /*剩下的字符串中还有不对应相等的字符*/
}
return true;/*剩下的字符都相等,包含i=j的情况*/
}
public:
bool validPalindrome(string s) {
for(int i=0,j=s.size()-1;i<j;i++,j--){
if(s[i]!=s[j])
return isrestPalindrome(s,i+1,j)||isrestPalindrome(s,i,j-1);
}
return true;/*不需要删除就是回文字符串*/
}
};
全代码:
//给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
#include<iostream>
#include<string>
using namespace std;
bool isrestPalindrome(string s, int i, int j) {/*判断:已删除一个字符,剩余字符串是不是回文字符串*/
/*i指针从【剩余字符串】的最左边开始,j从最右边开始*/
while (i < j) { /*i,j指针没有相遇时,继续循环*/
if (s[i++] != s[j--]) return false;
/*i指向的元素与j指向的元素不相等,即剩下的字符串中还有不对应相等的字符,即剩余字符串不是回文字符串,返回false*/
}
return true;
/*排除不是回文字符串的条件,即剩余字符都相等,包含i=j的情况,此时i,j是中心线上的字符)*/
}
bool validPalindrome(string s) {
for (int i = 0, j = s.size() - 1; i < j; i++, j--) {
/*使用双指针对整个字符串从两边向中间进行遍历,字符串元素位置标号为:0~s.size()-1*/
if (s[i] != s[j])
/*如果出现了两个指针指向字符不相等的情况,就需要判断:删掉一个字符后,剩余字符串是不是回文字符串*/
/*如果删掉一个字符,剩余字符串是回文字符串,那么满足题目条件,当返回true*/
/*反之,如果删掉一个字符串,剩余字符串不是回文字符串,那么就不满足题目条件,当返回false*/
/*根据以上所述,可以发现如果isrestPalindrome函数返回true,则validPalindrome就返回true,反之亦然*/
/*那么在需要删除一个字符的条件下,怎么样才能让函数返回一个false呢?
就是无论删i指针指向的字符还是j指针指向的字符,剩余字符串都不是回文字符串*/
/*怎么样才能让函数返回一个true呢?,只要删一个字符,无论是i还是j指针指向的元素,剩余字符串都是回文字符串*/
/*上面两行再简化理解一下,就是两个都是假,结果才能为假;只要有一个是真,那么结果就是真。
这样就会发现可以使用'||'运算符实现这样的效果 */
return isrestPalindrome(s, i + 1, j) || isrestPalindrome(s, i, j - 1);/**/
}
return true; /*不需要删除就是回文字符串,*/
}
int main() {
string str;
cout << "please input a string:" << endl;
cin >> str;
if(validPalindrome(str)) cout << "true" << endl; /*函数返回true,就输出一个"true"*/
else cout << "false" << endl; /*反之,输出一个"false"*/
return 0;
}