LeetCode 647 回文子串
【解题思路】
-
1.确定dp数组含义
-
布尔类型的dp[i][j]
-
表示区间范围[i,j]的子串是否为回文子串,如果是:dp[i][j]为true;否则为false
-
-
-
2.确定递推公式
-
s[i] == s[j]
-
情况一:下标i与j相同,也就是说同一个字符
-
dp[i][j] = true
-
例如a,是回文子串
-
-
情况二:下标i与j相差为1
-
dp[i][j] = true
-
例如aa,是回文子串
-
-
情况三:下标i与j相差大于1
-
此时s[i]与s[j]已经相同,看看区间内的子串是不是回文就行
-
if(dp[i+1][j-1])
-
-
-
s[i] != s[j]
-
dp[i][j] = false
-
-
-
3.初始化dp数组
-
将所有dp[i][j]全初始化为false
-
-
4.确定遍历顺序
-
从下到上
-
从左到右
-
保证dp[i+1][j-1]都是经过计算的
-
-
5.举例推导dp数组
【解题步骤】
-
1.将题目给出的字符串转成字符数组
-
2.定义一个dp数组,长度等于字符数组长度
-
3.定义一个统计回文子串数量的result变量
-
4.从后往前遍历字符串
-
j从i出发,往后遍历
-
递推公式
-
-
-
5.return result
【代码部分】
class Solution {
public int countSubstrings(String s) {
char[] chars = s.toCharArray();
boolean[][] dp = new boolean[chars.length][chars.length];
int result = 0;
for(int i = chars.length - 1; i >= 0 ; i--){
for(int j = i ; j < chars.length ; j ++){
if(chars[i] == chars[j]){
if(j - i <= 1){//情况1和情况2
result++;
dp[i][j] = true;
}else if(dp[i+1][j-1]){//情况3
result++;
dp[i][j] = true;
}
}
}
}
return result;
}
}
LeetCode 516 最长回文子序列
题目链接:516. 最长回文子序列 - 力扣(LeetCode)
【解题思路】
-
1.确定dp数组含义
-
dp[i][j]
-
字符串s在[i,j]范围内最长的回文子序列的长度为dp[i][j]
-
-
-
2.确定递推公式
-
s[i] == s[j]
-
dp[i][j] = dp[i+1][j+-1]+2
-
-
s[i] != s[j]
-
说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列
-
加入s[j]的长度
-
dp[i+1][j]
-
-
加入s[i]的长度
-
dp[i][j-1]
-
-
-
-
-
3.初始化dp数组
-
当i与j相同时
-
dp[i][j] = 1
-
-
剩余情况全初始为0
-
-
4.确定遍历顺序
-
从下到上
-
从左到右
-
-
5.举例推导dp数组
【解题步骤】
-
1.定义一个dp数组,长度等于字符串长度+1
-
2.从后往前遍历初始化dp[i][i]=1
-
3.从后往前遍历字符串
-
j从i出发,往后遍历
-
递推公式
-
-
-
5.return dp[0][len-1]
【代码部分】
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 i = s.length() - 1 ; i >= 0 ; i--){
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(dp[i][j],Math.max(dp[i+1][j],dp[i][j-1]));
}
}
}
return dp[0][s.length() - 1];
}
}