680.验证回文字符串 Ⅱ
双指针法
思路
在允许最多删除一个字符的情况下,同样可以使用双指针,通过贪心实现。初始化两个指针 low \textit{low} low 和 high \textit{high} high 分别指向字符串的第一个字符和最后一个字符。每次判断两个指针指向的字符是否相同,如果相同,则更新指针,将 low \textit{low} low 加 1, high \textit{high} high 减 1,然后判断更新后的指针范围内的子串是否是回文字符串。如果两个指针指向的字符不同,则两个字符中必须有一个被删除,此时我们就分成两种情况:即删除左指针对应的字符,留下子串 s [ low + 1 : high ] s[\textit{low} + 1 : \textit{high}] s[low+1:high],或者删除右指针对应的字符,留下子串 s [ low : high − 1 ] s[\textit{low} : \textit{high} - 1] s[low:high−1]。当这两个子串中至少有一个是回文串时,就说明原始字符串删除一个字符之后就以成为回文串。
代码实现
class Solution
{
public:
bool validPalindrome(string s)
{
bool flag = true;
int left = 0, right = s.length() - 1;
while (left < right)
{
if (s[left] == s[right])
{
left++;
right--;
}
else
{
return cheak(s, left + 1, right) || cheak(s, left, right - 1);
}
}
return true;
}
bool cheak(const string &s, int left, int right)
{
while (left < right)
{
if (s[left] == s[right])
{
left++;
right--;
}
else
{
return false;
}
}
return true;
}
};
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串的长度。判断整个字符串是否是回文字符串的时间复杂度是 O ( n ) O(n) O(n),遇到不同字符时,判断两个子串是否是回文字符串的时间复杂度也都是 O ( n ) O(n) O(n)
-
空间复杂度: O ( 1 ) O(1) O(1),只需要维护有限的常量空间。