代码随想录day60 | 动态规划P17 | ● 647. ● 516.● 动态规划总结篇

今天 结束动态规划章节 正好是60天 fighting

647. 回文子串

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

复制代码
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"

示例 2:

复制代码
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

思路

动态规划

**定义:**dpij 代表字符串在区间i, j上是不是回文子串 是则true 否则 false

**递推:**在确定递推公式时,就要分析如下几种情况。

整体上是两种,就是si与sj相等,si与sj不相等这两种。

当si与sj不相等,那没啥好说的了,dpij一定是false。

当si与sj相等时,这就复杂一些了,有如下三种情况

  • 情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
  • 情况二:下标i 与 j相差为1,例如aa,也是回文子串
  • 情况三:下标:i 与 j相差大于1的时候,例如cabac,此时si与sj已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dpi + 1j - 1是否为true。

**初始化:**全false即可

**遍历顺序:**注意到 dpij 在情况三由 其左下角的 dpi + 1j - 1决定 那么遍历要从下往上 从左往右

贪心

首先确定回文串,就是找中心然后向两边扩散看是不是对称的就可以了。

在遍历中心点的时候,要注意中心点有两种情况

一个元素可以作为中心点,两个元素也可以作为中心点。

代码

动态规划

java 复制代码
class Solution {
    public int countSubstrings(String s) {
        //dp[i][j] 代表 字符串中[i, j]区间的子串是否为回文串
        boolean [][] dp = new boolean [s.length()][s.length()];

        int num = 0;
        for(int i = s.length()-1 ; i >= 0; i--){
            for(int j = i; j < s.length();j++){
                if(s.charAt(i) == s.charAt(j)){
                     if(j - i <= 1){//情况一与情况二
                         dp[i][j] = true;
                         num++;
                     }else{
                         //情况三
                         dp[i][j] = dp[i+1][j-1];
                         if(dp[i][j]) num ++;
                     }
                }else{
                    dp[i][j] = false;
                }
            }
        }
        return num;
    }
}

贪心

java 复制代码
class Solution {
    public int countSubstrings(String s) {
        //确定回文串,就是找中心然后向两边扩散看是不是对称的就可以了。
        int res = 0;
        for (int i = 0; i < s.length(); i++) {
            //遍历每个字符作为中心点
            res += getNum(s, i, i, s.length());
            res += getNum(s, i, i + 1, s.length());
        }
        return res;
    }

    public int getNum(String s, int i, int j, int len) {
        int res = 0;
        while (i >= 0 && j < len && s.charAt(i) == s.charAt(j)) {
            //向两边扩散
            i--;
            j++;
            res++;
        }
        return res;
    }

}

516.最长回文子序列

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

示例 1:

复制代码
输入:s = "bbbab"
输出:4
解释:一个可能的最长回文子序列为 "bbbb" 。

示例 2:

复制代码
输入:s = "cbbd"
输出:2
解释:一个可能的最长回文子序列为 "bb" 。

思路

上一题求的是回文子串,而本题要求的是回文子序列, 要搞清楚这两者之间的区别。

回文子串是要连续的,回文子序列不是连续的! 回文子串,回文子序列都是动态规划经典题目。

定义:dpij:字符串s在i, j范围内最长的回文子序列的长度为dpij

递推:

在判断回文子串的题目中,关键逻辑就是看si与sj是否相同。

如果si与sj相同,那么dpij = dpi + 1j - 1 + 2;

如果si与sj不相同,说明si和sj的同时加入 并不能增加i,j区间回文子序列的长度,那么分别加入si、sj看看哪一个可以组成最长的回文子序列。

加入sj的回文子序列长度为dpi + 1j

加入si的回文子序列长度为dpij - 1

那么dpij一定是取最大的,即:dpij = max(dpi + 1j, dpij - 1);

**初始化:**根据dp定义 单个字符的最长回文子序列长度为1 那么斜向初始化为1

遍历顺序:dpij = max(dpi + 1j, dpij - 1); 所以dpij 与 其左下角元素有关

遍历从下到上 从左到右

代码

java 复制代码
class Solution {
    public int longestPalindromeSubseq(String s) {
        //dp[i][j]:字符串s在[i, j]范围内最长的回文子序列的长度为dp[i][j]。
        int [][] dp = new int [s.length()][s.length()];
        for(int i = 0; i<s.length(); i++){
            dp[i][i] = 1;
        }

        for(int i = s.length()-1; i>=0; i--){
//            System.out.println("i=" + i);
            //注意这里j初始化为 i + 1 防止出现越界问题
            for(int j = i + 1; j<s.length(); j++){
//                System.out.println("j=" + 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+1][j], dp[i][j-1]);
                }
            }
        }
        return dp[0][s.length()-1];
    }
}

动态规划总结篇

代码随想录 (programmercarl.com)

相关推荐
程序员黑豆6 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
GreenTea7 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
风流 少年7 小时前
Spring AI 2.0:Memory
java·后端·spring
码匠许师傅7 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
小席是个热心肠8 小时前
AI相关的自我学习
java·人工智能·学习
fqq38 小时前
力扣刷题前置Java语法
算法·leetcode·职场和发展
数智化管理手记10 小时前
海量数据如何沉淀有效数据资产?数据标准化治理方案如何搭建?
java·大数据·人工智能
半夏微凉半夏殇11 小时前
x11与weston对比,优先选哪个
leetcode·均值算法·eclipse
2501_9065651211 小时前
数学之美探究
算法
oier_Asad.Chen11 小时前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环