647. 回文子串
思路:
代码:
class Solution {
public int countSubstrings(String s) {
int n = s.length();
if(n == 1) return 1;
//i~j范围内的字符串是否为回文子串
boolean[][] dp = new boolean[n][n];
int res = 0;
for(int i = n - 1; i >= 0; i--){
char c1 = s.charAt(i);
for(int j = i; j < n; j++){
char c2 = s.charAt(j);
if(c1 == c2){
if(j - i <= 1){//如果当前字符串长度不超过2
dp[i][j] = true;
res++;
}else if(dp[i+1][j-1]){
dp[i][j] = true;
res++;
}
}
}
}
return res;
}
}
需要注意的点:
根据推导公式确定遍历顺序(行从下向上)
516.最长回文子序列
思路:
代码:
class Solution {
public int longestPalindromeSubseq(String s) {
int n = s.length();
if(n == 1) return 1;
int[][] dp = new int[n][n];
//根据递推公式,i\j相等的情况推导不到
for(int i = 0; i < n; i++){
dp[i][i] = 1;
}
for(int i = n-1; i >= 0; i--){
char c1 = s.charAt(i);
for(int j = i+1; j < n; j++){
char c2 = s.charAt(j);
if(c1 == c2){
dp[i][j] = dp[i+1][j-1] + 2;
}else{
dp[i][j] = Math.max(dp[i][j-1], dp[i+1][j]);
}
}
}
return dp[0][n-1];
}
}
需要注意的点:
遍历顺序、初始化都要根据递推公式来决定。