最長迴文子序列(IPS)


dp[i][j]:字符串s在[i, j]範圍內最長的迴文子序列的長度

  • 遞歸解法:

1.如果str的最後一個元素和第一個元素是相同的,則有:lps(0,n-1)=lps(1,n-2)+2;例如字符串序列“AABACACBA”,第一個元素和最後一個元素相同,其中lps(1,n-2)表示紅色部分的最長迴文子序列的長度;

2.如果str的最後一個元素和第一個元素是不相同的,則有:lps(0,n-1)=max(lps(1,n-1),lps(0,n-2));例如字符串序列“ABACACB”,其中lps(1,n-1)表示去掉第一元素的子序列,lps(0,n-2)表示去掉最後一個元素的子序列。

class Solution:
    def Circle(self,s,left,right):
        if(left==right):
            return 1
        elif(left>right):
            return 0
        else:
            if(s[left]!=s[right]):
                return max(self.Circle(s,left,right-1),self.Circle(s,left+1,right))
            else:
                return self.Circle(s,left+1,right-1)+2
    def longestPalindromeSubseq(self, s: str) -> int:
        if len(s)==1:
            return 1
        if s[0]==s[-1]:
            return self.Circle(s,1,len(s)-2)+2
        else:
            return max(self.Circle(s,1,len(s)-1),self.Circle(s,0,len(s)-2))
        return maxnum*2

  • 動態規劃:

定義:d[i][j] 表示最大的迴文字符串的長度

初始化:d[i][i] = 1 其他均爲0,通過j \in [i+1,...)保持 i<j

i從length自高向低遍歷,因爲[i+1][j-1]需要上一級的結果,只求[i,j]範圍內的解。i+1>j-1時因爲j>=i+1,所以會落在(i+1,i)上,該點位於下半側爲0。

考慮兩種情況:s[i] == s[j] d[i+1][j-1]+2s[i] != s[j] max(d[i+1][j], d[i][j-1])

如果[3][4]->[4][3],因爲位於下半邊的值默認爲0,所以不會影響結果

最終結果: d[1][length] 其中n是字符串的長度

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        length=len(s)
        dp=[[0]*(length+1) for i in range(length+1)]
        for i in range(1,length+1):
            dp[i][i]=1
        for i in range(length,0,-1):
            for j in range(i+1,length+1):
                if s[i-1]==s[j-1]:
                    # 因爲要求[i+1]所以必須得到上一層的解,所以要從高層length往底層1遍歷
                    dp[i][j]=dp[i+1][j-1]+2
                else:
                    dp[i][j]=max(dp[i][j-1],dp[i+1][j])
        return dp[1][length]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章