題目描述
leetcode 題目鏈接:https://leetcode-cn.com/problems/valid-palindrome-ii/submissions/
給定一個非空字符串 s,最多刪除一個字符。判斷是否能成爲迴文字符串。
示例 1:
輸入: "aba"
輸出: True
示例 2:
輸入: "abca"
輸出: True
解釋: 你可以刪除c字符。
注意:
字符串只包含從 a-z 的小寫字母。字符串的最大長度是50000。
題目分析
解法一:暴力解法,刪除每一個字符判斷剩下的是否是迴文字符串,時間複雜度:O();空間複雜度:O(n)。
解法二:貪心算法,首先考慮如果不允許刪除字符,如何判斷一個字符串是否是迴文串。常見的做法是使用雙指針。定義左右指針,初始時分別指向字符串的第一個字符和最後一個字符,每次判斷左右指針指向的字符是否相同,如果不相同,則不是迴文串;如果相同,則將左右指針都往中間移動一位,直到左右指針相遇,則字符串是迴文串。
在允許最多刪除一個字符的情況下,同樣可以使用雙指針,通過貪心算法實現。初始化兩個指針 low 和 high 分別指向字符串的第一個字符和最後一個字符。每次判斷兩個指針指向的字符是否相同,如果相同,則更新指針,令 low = low + 1
和 high = high - 1
,然後判斷更新後的指針範圍內的子串是否是迴文字符串。如果兩個指針指向的字符不同,則兩個字符中必須有一個被刪除,此時我們就分成兩種情況:即刪除左指針對應的字符,留下子串 s[low + 1], s[low + 1], ..., s[high]
,或者刪除右指針對應的字符,留下子串 s[low]
, s[low + 1], ..., s[high - 1]
。當這兩個子串中至少有一個是迴文串時,就說明原始字符串刪除一個字符之後就以成爲迴文串。
時間複雜度:O(n);
空間複雜度:O(1)。
代碼
class Solution:
def validPalindrome(self, s):
left = 0
right = len(s) - 1
while left < right:
if s[left] != s[right]:
return self.Palindrome(s, left, right-1) or self.Palindrome(s, left+1, right)
left += 1
right -= 1
return True
def Palindrome(self, s, left, right):
while left <= right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True