题目

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

示例 1:
输入: “aba”
输出: True

示例 2:
输入: “abca”
输出: True
解释: 你可以删除c字符。

注意:

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

    方案一(暴力法)

    1. class Solution:
    2. def validPalindrome(self, s: str) -> bool:
    3. if self.isPalindrome(s):
    4. return True
    5. for i in range(len(s)):
    6. if self.isPalindrome(s[:i] + s[i+1:]):
    7. return True
    8. return False
    9. def isPalindrome(self, s: str) -> bool:
    10. length = len(s)
    11. for i in range(length // 2):
    12. if s[i] != s[length - i - 1]:
    13. return False
    14. return True
  • 时间复杂度 验证回文字符串 Ⅱ - 图1
  • leetcode 超时

    方案二(递归)

    1. class Solution:
    2. def validPalindrome(self, s: str) -> bool:
    3. def helper(s: str, isDeleted: bool) -> bool:
    4. length = len(s)
    5. if length <= 1:
    6. return True
    7. if s[0] == s[length - 1]:
    8. return helper(s[1:length-1], isDeleted)
    9. elif isDeleted: # 已经删除过字符了
    10. return False
    11. else:
    12. return helper(s[1:], True) or helper(s[:length-1], True)
    13. return helper(s, False)

    方案三(双指针)

    1. class Solution:
    2. def validPalindrome(self, s: str) -> bool:
    3. if len(s) <= 0:
    4. return False
    5. if s == s[::-1]:
    6. return True
    7. left = 0
    8. right = len(s) - 1
    9. while left < right:
    10. if s[left] == s[right]:
    11. left += 1
    12. right -= 1
    13. else:
    14. s1 = s[:left] + s[left+1:]
    15. s2 = s[:right] + s[right+1:]
    16. if s1 == s1[::-1] or s2 == s2[::-1]:
    17. return True
    18. else:
    19. return False

    参考链接

    https://leetcode-cn.com/explore/featured/card/2020-top-interview-questions/281/string/1258/