01-动态规划专项-力扣第五题

最长回文子串

问题描述:

给你一个字符串 s,找到 s 中最长的回文子串。

示例1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例2:

输入:s = "cbbd"
输出:"bb"

示例3:

输入:s = "a"
输出:"a"

示例4:

输入:s = "ac"
输出:"a"

思路:

  • 既然是动态规划专场,这里就只介绍动态规划的思路。

回文串有先天性的转移特性,如果一个字符串是回文串,那么它去掉首位的子串也是一个回文串,当然需要这个回文串长度严格大于2才成立。

这样我们就可以用来定义回文串的转移方程。如果 i 和 j 位置上的字符相同的话,那么[ i j ]是否为回文串就取决于[ i + 1 j + 1]是否是回文串。这样我们就找到了转移方程。

当然还需要一些细节需要处理,比如边界和初始值。

易知,单个字符是回文串,所以长度为1的子串一定是回文串。至于边界,我们遍历到从0到n-1的所有值即可。

当 i 和 j 对应的字符相等的时候,如果 i 和 j 之间没有字符,或者只有一个字符,那么直接判定为回文串,也就是当j-i<3的时候

Java代码

/**
    * @Description: 动态规划专项第一题 力扣第五题 中等
    * @return: 返回结果
    * @Author: Mr.Gao
    * @Date: 2021/7/31
    */
    public String longestPalindrome(String s) {
        char[] chars = s.toCharArray();
        int n = chars.length;
        if(n<2){
            return s;
        }

        int start=0;
        int maxLength=1;

        //dp[i][j]表示chars[i]~char[j]是否为回文串
        boolean[][] dp = new boolean[n][n];
        for(int i=0;i<n;i++){
            dp[i][i] = true;
        }
        for (int j = 1; j < n; j++) {
            for (int i = 0; i < j; i++) {
                if (chars[i] != chars[j]) {
                    dp[i][j] = false;
                } else {
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }
                if (dp[i][j] && j - i + 1 > maxLength) {
                    maxLength = j - i + 1;
                    start = i;
                }
            }
        }
        return s.substring(start,start+maxLength);
    }
上一篇:leetcode443. 压缩字符串


下一篇:[剑指offer专项突击版-Java解法]剑指 Offer II 019. 最多删除一个字符得到回文