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,通過保持
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]+2
,s[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]