516.最长回文子序列
一. leetcode题目链接
https://leetcode-cn.com/problems/longest-palindromic-subsequence/
二. 动态规划
- 样本:“cabbeaf”
- 状态转移
(1) 如果一个字符串S[0,1,2,3,,,n-1],S[0] == S[n-1]那么最大回文子序列就是
P(left,right) = P(left+1,right-1) + 2 (left表示字符串的起点,right表示字符串 的终点)
(2) 如果这个字符串S[0]!= S[n-1]则
P(left,right) = max{ P(left+1,right),p(left,right-1)}
- 边界
字符串长度为1 的最大回文子串长度为1
- 例子
下图表示,从dp[left][right]这个区间的字符串的最大回文是多大,
比如dp[0][3]表示”cabb”的最大回文子序列长度是2。
比如dp[1][1]表示”a”的最大回文子序列长度是1
初始化,所有dp[i][i]的回文子序列长度是自己本身,所以是1,(蓝色底部)
开始动态规划程序:(从左下到右上,按照长度为2 的字符串,长度为3,4,5,依次增加)
程序:
public int longestPalindromeSubseq(String s) { if (s.length() == 0 || s == null) { return 0; } int length = s.length(); char[] str = s.toCharArray(); int[][] dp = new int[length][length]; for (int i = 0; i < length; i++) { dp[i][i] = 1; } //String maxStr = s.substring(0,0); for (int i = 1; i < length; ++i) { int tmp = 0; for (int j = 0; j + i < length; ++j) { if (str[j] == str[i + j]) { tmp = dp[j + 1][i + j - 1] + 2; //这个记录了最大的子序列,本题中没用过 //maxStr = str[j] + maxStr + str[j]; } else { tmp = Math.max(dp[j + 1][i + j], dp[j][i + j - 1]); } dp[j][j + i] = tmp; } } return dp[0][length - 1]; }