驗證迴文字符串II(貪心算法)

題目描述

leetcode 題目鏈接:https://leetcode-cn.com/problems/valid-palindrome-ii/submissions/

給定一個非空字符串 s,最多刪除一個字符。判斷是否能成爲迴文字符串。

示例 1:

輸入: "aba"
輸出: True
示例 2:

輸入: "abca"
輸出: True
解釋: 你可以刪除c字符。
注意:

字符串只包含從 a-z 的小寫字母。字符串的最大長度是50000。

題目分析

解法一:暴力解法,刪除每一個字符判斷剩下的是否是迴文字符串,時間複雜度:O(n2n^2);空間複雜度:O(n)。

解法二:貪心算法,首先考慮如果不允許刪除字符,如何判斷一個字符串是否是迴文串。常見的做法是使用雙指針。定義左右指針,初始時分別指向字符串的第一個字符和最後一個字符,每次判斷左右指針指向的字符是否相同,如果不相同,則不是迴文串;如果相同,則將左右指針都往中間移動一位,直到左右指針相遇,則字符串是迴文串。
在這裏插入圖片描述
在允許最多刪除一個字符的情況下,同樣可以使用雙指針,通過貪心算法實現。初始化兩個指針 low 和 high 分別指向字符串的第一個字符和最後一個字符。每次判斷兩個指針指向的字符是否相同,如果相同,則更新指針,令 low = low + 1high = 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    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章