回文子串 LeetCode 647
题目链接:[LeetCode 647 - 中等]
思路
使用动态规划,并且从后向前遍历。
情况1:单个字符->为回文子串、 情况2:两个字符 代码:if(chars[i]==chars[j]){if(j-i<=1){res++;dp[i][j]=true;}
情况3:内部为回文子串且坐标为i和j的部分相等 代码:if(chars[i]==chars[j]){else if(dp[i+1][j-1]){res++;dp[i][j]=true; }}
动态规划:
class Solution {
public int countSubstrings(String s) {
char[] chars = s.toCharArray();
int len = chars.length;
int res=0;
boolean[][] dp = new boolean[len][len];
for(int i=len-1;i>=0;i--){
for(int j=i;j<len;j++){
if(chars[i]==chars[j]){
if(j-i<=1){
res++;
dp[i][j]=true;
}else if(dp[i+1][j-1]){
res++;
dp[i][j]=true;
}
}
}
}
return res;
}
}
最长回文子序列 LeetCode 516
题目链接:[LeetCode 516 - 中等]
思路
动规五部曲:
①dp数组的含义: dp[i][j]:字符串s在[i, j]范围内最长的回文子序列的长度为dp[i][j] 。
②递推公式: dp[i][j]=dp[i+1][j-1]+2
③初始化: dp[i][i]=1; 当i与j相同,那么dp[i][j]一定是等于1的
④遍历顺序: for (int i = s.size() - 1; i >= 0; i--) { for (int j = i + 1; j < s.size(); j++)
dp[i][j] 依赖于 dp[i + 1][j - 1] ,dp[i + 1][j] 和 dp[i][j - 1]
⑤举例推导dp数组(略)
动态规划:
class Solution {
public int longestPalindromeSubseq(String s) {
int[][] dp = new int[s.length()+1][s.length()+1];
for(int i=s.length()-1;i>=0;i--){
dp[i][i]=1;
for(int j=i+1;j<s.length();j++){
if(s.charAt(i)==s.charAt(j)){
dp[i][j]=dp[i+1][j-1]+2;
}else{
dp[i][j]=Math.max(Math.max(dp[i+1][j],dp[i][j-1]),dp[i][j]);
}
}
}
return dp[0][s.length()-1];
}
}