每日一题(2020-05-19)680. 验证回文字符串 Ⅱ

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

难度简单182收藏分享切换为英文关注反馈

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

示例 1:

输入: "aba"
输出: True

示例 2:

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

注意:

  1. 字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-palindrome-ii

解法一:枚举法

依次删除掉每一个位置的字符,判断剩余字符串是否组成回文串。该方法复杂度过高,无法通过。

时间复杂度:O(n2)

空间复杂度:O(1)

解法二:贪心算法

初始化两个指针 low = 0high = s.length() - 1。依次判断两个指针指向的字符是否相同,如果相同,则 low = low + 1high = high - 1。如果两个指针指向的字符不同,则两个字符中必须有一个被删除,此时分成两种情况讨论:

  • 删除左指针对应的字符,留下子串 s[low + 1], s[low + 1], ..., s[high]
  • 删除右指针对应的字符,留下子串 s[low], s[low + 1], ..., s[high - 1]

当这两个子串中至少有一个是回文串时,就说明原始字符串删除一个字符之后就以成为回文串。

class Solution {
    public boolean validPalindrome(String s) {
        int low = 0, high = s.length() - 1;
        while (low < high) {
            char c1 = s.charAt(low), c2 = s.charAt(high);
            if (c1 == c2) {
                low++;
                high--;
            } else {
                boolean flag1 = true, flag2 = true;
                //判断删除左指针对应的字符后,余下的是否为回文串
                for (int i = low + 1, j = high; i < j; i++, j--) {
                    char c3 = s.charAt(i), c4 = s.charAt(j);
                    if (c3 != c4) {
                        flag1 = false;
                        break;
                    }
                }
              //判断删除右指针对应的字符后,余下的是否为回文串
                for (int i = low, j = high - 1; i < j; i++, j--) {
                    char c3 = s.charAt(i), c4 = s.charAt(j);
                    if (c3 != c4) {
                        flag2 = false;
                        break;
                    }
                }
                return flag1 || flag2;
            }
        }
        return true;
    }
}

时间复杂度:O(n),其中 n 是字符串的长度。判断整个字符串是否是回文字符串的时间复杂度是 O(n),当遇到不同字符时,判断删除左、右指针对应的字符后所剩下的字符串是否是回文字符串的时间复杂度也都是 O(n)。

空间复杂度:O(1)

你可能感兴趣的:(LeetCode,每日一题)