一个子串左右两个元素相等,并且中间对称,才是回文子串
即 i=j 时,[i+1: j-1]对称
dp[i][j]: [i:j] 是否是回文字串
当 子串长度大于2 由 dp[i+1][j-1] 推出, i 由 i+1推出 所以 i 要倒序
不大于2时,则由 i j 决定
- class Solution {
- public int countSubstrings(String s) {
- int length = s.length();
- boolean dp[][] = new boolean[length][length];
- // dp[i][j] [i:j] 是否是回文字串
-
- int res = 0;
- for(int i = length-1; i > -1; i--){
- for(int j = i; j < length; j++){
- if(s.charAt(i) == s.charAt(j)){
- if(j-i <= 1){ // 字串长度不超过2
- dp[i][j] = true;
- res++;
- }else if(dp[i+1][j-1]){
- dp[i][j] = true;
- res++;
- }
- }
- }
- }
- return res;
- }
- }
子序列可以不连续 所以当 s[i] != s[j] 也需要考虑
s[i] == s[j] 时,中间的长度 + 2
s[i] != s[j] 时,要考虑左右两个哪个加入中间后更长
- class Solution {
- public int longestPalindromeSubseq(String s) {
- int length = s.length();
- int[][] dp = new int[length][length];
-
- for(int i = length-1; i > -1; i--){
- dp[i][i] = 1; // 字串长度为 1 必然相等
- for(int j = i + 1; j < length; j++){
- if(s.charAt(i) == s.charAt(j)){
- dp[i][j] = dp[i+1][j-1] + 2; // dp[1][2] = dp[2][1] + 2 = 0 + 2
- }else{
- dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
- }
- }
- }
- return dp[0][length-1];
- }
- }
