1、题目描述:
给你一个字符串 s
,最多 可以从中删除一个字符。
请你判断 s
是否能成为回文字符串:如果能,返回 true
;否则,返回 false
。
示例 1:
输入:s = "aba"
输出:true
示例 2:
输入:s = "abca"
输出:true
解释:你可以删除字符 'c' 。
示例 3:
输入:s = "abc"
输出:false
提示:
1 <= s.length <= 105
s
由小写英文字母组成
2、代码:
cpp
class Solution {
public:
// 辅助函数:判断子串 [left, right] 是否为回文
bool isPalindNum(string s, int left, int right) {
// 使用双指针法检查子串是否为回文
while (left < right) {
if (s[left] != s[right]) {
// 如果左右字符不相等,说明不是回文,返回 false
return false;
}
left++; // 左指针向右移动
right--; // 右指针向左移动
}
// 如果循环结束,说明子串是回文,返回 true
return true;
}
// 主函数:判断字符串 s 是否可以通过最多删除一个字符成为回文
bool validPalindrome(string s) {
int left = 0, right = s.size() - 1; // 定义左右指针
// 使用双指针法遍历字符串
while (left < right) {
if (s[left] == s[right]) {
// 如果左右字符相等,继续向内移动指针
left++;
right--;
continue; // 跳过后续逻辑,继续下一次循环
} else {
// 如果左右字符不相等,尝试跳过左边或右边的字符
// 跳过左边字符:检查子串 [left+1, right] 是否为回文
// 跳过右边字符:检查子串 [left, right-1] 是否为回文
return isPalindNum(s, left + 1, right) ||
isPalindNum(s, left, right - 1);
}
}
// 如果循环结束,说明字符串已经是回文,返回 true
return true;
}
};
3、解题思路
-
回文的定义:
- 一个字符串是回文,当且仅当从左到右和从右到左读起来是一样的。
-
双指针法:
- 使用两个指针
left
和right
分别指向字符串的开头和结尾。 - 如果
s[left] == s[right]
,则继续向内移动指针(即left++
和right--
)。 - 如果
s[left] != s[right]
,说明需要删除一个字符:- 尝试跳过左边的字符(即检查子串
s[left+1] 到 s[right]
是否为回文)。 - 或者尝试跳过右边的字符(即检查子串
s[left]到 s[right-1]
是否为回文)。
- 尝试跳过左边的字符(即检查子串
- 如果上述两种情况中任意一种满足回文条件,则返回
true
;否则返回false
。
- 使用两个指针
-
辅助函数:
- 定义一个辅助函数
isPalindromeRange
,用于检查某个子串是否为回文。
- 定义一个辅助函数