###### tags: `Leetcode` `medium` `dynamic programming` `python` `c++` # 516. Longest Palindromic Subsequence ## [題目連結:] https://leetcode.com/problems/longest-palindromic-subsequence/ ## 題目: Given a string ```s```, find the longest palindromic **subsequence**'s length in s. A **subsequence** is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements. **Example 1:** ``` Input: s = "bbbab" Output: 4 Explanation: One possible longest palindromic subsequence is "bbbb". ``` **Example 2:** ``` Input: s = "cbbd" Output: 2 Explanation: One possible longest palindromic subsequence is "bb". ``` ## 解題想法: * 此題為給一字符串,求最長的回文子序列長度 * 子序列: 不需要連續 * 使用DP: * 定義dp[i][j]: **s[i]~s[j]中最長的回文長度** * 初始: for i in range(len(s)): dp[i][i]=1 * dp[i][j]=case1+case2 * **case1:** * 若當前首尾s[i]==s[j]相同,則繼承內縮的dp[i+1][j-1],並再將長度+2 * dp[i][j]=dp[i+1][j-1]+2 * **case2:** * 若首尾s[i]!=s[j],則選則去掉 **s[i]** or **s[j]** 後對於dp結果最長者 * dp[i][j]=max(dp[i+1][j], dp[i][j-1 * 注意: * 第一圈遍歷i從**尾到頭**!! * 第二圈j為range(i+1~n) * 因為最後是要求i=0,且確保j皆在i後面,若j>i,則dp[i][j]=0 ## Python: ``` python= class Solution(object): def longestPalindromeSubseq(self, s): """ :type s: str :rtype: int """ #dp[i][j]: s[i]~s[j]可組成的最長回文 #case1: if s[i]==s[j] 加2內縮: dp[i][j]= dp[i+1][j-1]+2 #case2: if s[i]!=s[j] : dp[i][j]=max(dp[i+1][j],dp[i][j-1]) 刪j or i n=len(s) dp=[[0 for _ in range(n)] for _ in range(n)] for i in range(n-1, -1, -1): dp[i][i]=1 for j in range(i+1, n): if s[i]==s[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][n-1] ``` ## C++: ``` cpp= class Solution { public: int longestPalindromeSubseq(string s) { int n=s.size(); vector<vector<int>> dp(n, vector<int>(n,0)); for (int i=n-1; i>=0; i--){ dp[i][i]=1; for (int j=i+1; j<n; j++){ if (s[i]==s[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][n-1]; } }; ```