タイトル説明
文字列を与えられたs
最長の回文配列を見つけるために、。これは、と仮定することができるs
最大長1000
。
输入:"bbbab"
输出:4 // 一个可能的最长回文子序列为 "bbbb"。 注意是“子序列”
問題解決のためのアイデア
一般的な質問のサブシーケンスの問題は、我々は、ルーチンおよびソリューションマスターする必要があります。サブシーケンスの問題の一般的なアイデアを|最長の回文配列。
-
動的計画法(4つの要素):
-
状態が表す:
dp[i][j]
表しs
の第i
二の文字j
の文字からなる部分文字列を、パリンドローム配列の最長の長さです。 -
状態遷移方程式:
- もし
s
最初i
の文字とj
同じ言葉の文字:dp[i][j] = dp[i + 1][j - 1] + 2
- もし
s
最初i
の文字とj
異なるものの文字:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
注:注横断方向のDP、と
i
最後の文字から、前方横断j
からi + 1
あなたは、各サブ質問が良いとされていることを確認することができますので、次のトラバーサルの始まり。(容易に利用可能な状態のビデオの状態遷移方程式に係る結論この遷移) - もし
-
初期設定:
dp[i][i] = 1
最長の回文配列は、単一の文字であるため、1
-
リターン結果:
dp[0][n - 1]
-
参照コード
class Solution {
public:
int longestPalindromeSubseq(string str) {
int length = str.size();
vector<vector<int> > dp(length, vector<int>(length, 0));
for(int i = 0; i < length; i++)
dp[i][i] = 1;
for(int i = length-2; i >= 0; i--){
for(int j = i+1; j < length; j++){
if(str[i] == str[j])
dp[i][j] = dp[i+1][j-1] + 2;
else
dp[i][j] = max(dp[i+1][j], dp[i][j-1]);
}
}
return dp[0][length-1];
}
};