Day57 动态规划 part17
我的思路:
这次的dp[i][j]含义是字符串从 i 到 j 是否为回文字符串
如果 i 和 j 处的字符相同:
长度为1 or 2,必然为回文串
长度>2,判断去掉首尾后的子串dp[i + 1][j - 1]是否也是回文子串(这就要求我们从下往上,从左往右遍历)
状态转移方程:
解答:
class Solution {
public int countSubstrings(String s) {
int result = 0;
char[] sc = s.toCharArray();
int len = s.length();
boolean[][] dp = new boolean[len][len];
for(int i = len - 1; i >= 0; i--) {
for(int j = i; j < len; j++) {
if(sc[i] == sc[j]) {
if(j - i <= 1) {
dp[i][j] = true;
result++;
}
else if(dp[i + 1][j - 1]) {
dp[i][j] = true;
result++;
}
}
}
}
return result;
}
}
我的思路:
这道题可以参考上面题的思路
这次不用true、false以及count计数,用dp[i][j]表示回文子串长度
初始化dp数组dp[i][i]为1(单个字符一定为回文)
这里for循环遍历时,j从i + 1开始,跳过了长度为2的字符串判断,使得当sc[i] == sc[j]时,统一 + 2
状态转移方程:
解答:
class Solution {
public int longestPalindromeSubseq(String s) {
int maxlen = 0;
char[] sc = s.toCharArray();
int len = s.length();
int[][] dp = new int[len][len];
for(int i = 0; i < len; i++) {
dp[i][i] = 1;
}
for(int i = len - 1; i >= 0; i--) {
for(int j = i + 1; j < len; j++) {
if(sc[i] == sc[j]) {
dp[i][j] = dp[i + 1][j - 1] + 2;
}
else {
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][len - 1];
}
}