文章目录
- 最长回文子串
- 代码解答:
 
- 不同的二叉搜索树
- 代码解答:
 
 
最长回文子串

 首先我们应该先了解什么是回文子串:
单个字符 例如 a 这也是回文字符串
2个字符 aa 或者 bb 这也是回文字符串
3个字符 aba 或者 bab
多个字符 abba ababa 这些也被叫做回文子串
从前到后和从后到前念的顺序一样的被叫做回文字符串
 再回到题目,这道题我们采用动态规划来解决:
 我们需要先定义1个容器dp(dp 为二维数组)
//其中len为题目给的字符串s的长度
    boolean[][] dp = new boolean[len][len];
我们定义1个i和j,i和j表示的是从i到j的所组成的数组
 因为我们之前谈过单个字符也是回文子串,因此当i和j相等时表示的就是单个字符 例如: ad dp[0][0]表示的就是 a,因此我们将dp[i][i] 全部设置为true
         boolean[][] dp = new boolean[len][len];
         for(int i = 0;i<len;i++){
             dp[i][i] = true;
         }
对应的容器:
 
 在这个容器中我们只需要看左下脚,因为我们定义的是从i到j,i必须要小于j
 之后我们就需要将左下角的填满
        char[] c = s.toCharArray();
        for(int j = 1;j<len;j++){
            for(int i = 0;i<len-1&&i<j;i++){
                if(c[i] != c[j]){
                    dp[i][j] = false;
                }else{
                    if(j-i+1 < 3){
                        dp[i][j] = true;
                    }else{
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
从容器中可以看出我们i是从0到3即0到 len - 1,j是从1到4即 1到 len,
 如果dp[i] 和 dp[j] 不一样那肯定是不符合题意的,如 abc , a 和 c不相等,直接置为false;
 如果相等我们又要考虑 aa 这种情况,如果两边的都相等了,长度还是小于3就没必要再往里走了。就可以直接置为true, 如果长度大于3我们就往里走,即dp方程 dp[i][j] = dp[i+1][j-1]; 这个dp方程的意思就是i往左走,j往右走,即
 
 之后我们只需要拿到最大的长度max,通过切割就可以得到
            if(dp[i][j] && j-i+1 > max){
                    max = j-i+1;
                    start = i;
                }
            }
        }
        return s.substring(start,start+max);
代码解答:
class Solution {
    public String longestPalindrome(String s) {
          int len = s.length();
          if(len == 1){
              return s;
          }
          //定义容器
         boolean[][] dp = new boolean[len][len];
         for(int i = 0;i<len;i++){
             dp[i][i] = true;
         }
         int start = 0;
         int max = 1;
         char[] c = s.toCharArray();
        for(int j = 1;j<len;j++){
            for(int i = 0;i<len-1&&i<j;i++){
                if(c[i] != c[j]){
                    dp[i][j] = false;
                }else{
                    if(j-i+1 < 3){
                        dp[i][j] = true;
                    }else{
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
                if(dp[i][j] && j-i+1 > max){
                    max = j-i+1;
                    start = i;
                }
            }
        }
        return s.substring(start,start+max);
    }
}
不同的二叉搜索树

 这道题也是动态规划,我们需要先定义容器
        int[] dp = new int[n+1];
这道题要找到dp方程我们就需要将每个数都当作一次根节点,将它们能二叉搜索树相加就可以,我们这里画出一个区间更好理解:
 
 我们在i个元素中选择1个j当作根节点 那么比j小的 j-1个数就可以组成j的左子树,比j大的就可以组成j的右子树。 它们总共能组成的二叉搜索树也就是相乘的关系。
 for(int i = 1;i<=n;i++){
            //让n个节点都当一次头节点
            for(int j = 1;j<=i;j++){
                dp[i] += dp[j-1] * dp[i-j];
            }
        }
代码解答:
class Solution {
    public int numTrees(int n) {
       //动态规划
        int[] dp = new int[n+1];
        dp[0] = 1;
        for(int i = 1;i<=n;i++){
            //让n个节点都当一次头节点
            for(int j = 1;j<=i;j++){
                dp[i] += dp[j-1] * dp[i-j];
            }
        }
        return dp[n];
    }
}



















