680. 验证回文字符串 Ⅱ

88 阅读2分钟

[680. 验证回文字符串 Ⅱ]

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

题目描述

给定一个非空字符串 s最多删除一个字符。判断是否能成为回文字符串。。

示例

示例1 :

输入: s = "aba"
输出: true

示例 2:

输入: s = "abca"
输出: true
解释: 你可以删除c字符。

示例 3:

输入: s = "abc"
输出: false

提示:

  • 1 <= s.length <= 105
  • s 由小写英文字母组成

acbba abbca acccba abc cba

思路

这道题与昨天的那道题相比,有了些变化,首先就是少了无效字符的干扰,在代码层面判断比较简单,但是多了一次跳过的机会。先讨论一下双指针的首位指针法,在发生不相等的时候,是要将这个跳过的机会给那边呢,在这道题里面,明显是都需要考虑,即或的关系。整体翻转法在比较时也需要是将机会给原字符串,还是翻转字符串,同样也是或的关系。而翻转部分和栈的办法,会将问题复杂化,这里就不讨论了。

代码实现

我们使用首位指针法,注意到,回文串的中心部分也是字符串,所以我们另外定义了一个判断回文串的函数,加上了字符串的范围。

class Solution {
private:
    // 是否为回文串
    bool isHuiWen(const string& s, int left, int right) {
        for (; left < right; ++left, --right) {
            if (s[left] != s[right]) {
                return false;
            }
        }
        return true;
    }

public:
    bool validPalindrome(string s) {
        int left = 0, right = s.size() - 1;

        while (left < right) {      //处理未出错的部分
            if (s[left] == s[right]) {
                ++left;
                --right;
            }
            else {  // left和right指向的字符不等时,说明须删除其中一个。分两种情况,只要其中一种满足回文子串 就可说明原始字符串删除一个字符之后可以成为回文串
                return isHuiWen(s, left, right - 1) || isHuiWen(s, left + 1, right);
            }
        }

        return true;
    }
};

总结

在链表上使用双指针,回文串针对出现一个错误进行了另外的讨论。