当前位置 博文首页 > 阳阳的博客:【leetcode.5】最长回文子串

    阳阳的博客:【leetcode.5】最长回文子串

    作者:[db:作者] 时间:2021-08-14 18:00

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 最长回文子串

    一、要求

    给定一个字符串?s,找到?s?中最长的回文子串。你可以假设?s?的最大长度为1000。

    示例 1:

    输入: "babad"
    输出: "bab"
    注意: "aba"也是一个有效答案。
    

    示例 2:

    输入: "cbbd"
    输出: "bb"

    二、解法

    这里我们采用动态规划。

    主要思路:

    (1)声明一个布尔类型的二维数组dp,boolean[][] dp = new boolean[len][len],len为字符串s的长度,那么如果dp[i][j]为true时,则表示字符串s从第i个位置开始到第j个位置结束之间的子字符串为回文子串。

    如:s="abac",那么此时dp声明为dp[4][4],那么dp[0][0],dp[1][1],dp[2][2],dp[3][3],dp[0][2]都为true,表示对应位置的字母都是回文子串,那么这里最大长度的回文子串为aba。

    (2)如果dp[i][j]为true,那么dp[i+1][j-1]也必定为true,即“abba”为回文子串,那么“bb”也为回文子串。因此我们的状态转移方程为dp[i+1][j-1]=true&&s.charAt(i)==s.charAt(j)? =>? dp[i][j]为true。

    (3)如果j-i<=2时,即可能为回文的字符串最大长度为3时,如果有s.charAt(i)==s.charAt(j),就直接断定dp[i][j]=true,并不需要dp[i+1][j-1]=true。即当s="abad",i=0;j=2,s.charAt(0)==s.charAt(2),则直接判定aba为回文字符串,即dp[0][2]=true。

    (4)使用两层for循环,外层循环指示器i控制所求字符串的开始位置,内层循环指示器j控制所求字符串的结束位置。但不是简单的使得i从0开始,i++,j=i,j++,而是需要i从最大值开始,即字符串的长度-1开始,i--,j=i,j++,先求出小范围内下标大的dp情况,再求出大范围内下标小的情况,因为后者依赖前者。例如dp[0][3]依赖dp[1][2]的值。


    三、代码演示

     public String longestPalindrome(String s) {
            if (s == null || s.equals("")) {
                return "";
            }
            int len = s.length();
            boolean[][] dp = new boolean[len][len];
            int maxLen = 0;
            int start = 0;
            int stop = 0;
            for (int i = len - 1; i >= 0; i--) {
                for (int j = i; j < len; j++) {
                    if ((s.charAt(i) == s.charAt(j)) && (j - i <= 2 || dp[i + 1][j - 1])) {
                        dp[i][j] = true;
                        if (maxLen < j - i + 1) {
                            maxLen = j - i + 1;
                            start = i;
                            stop = j;
                        }
                    }
                }
            }
            return s.substring(start, stop + 1);
        }

    代码提交结果:


    四、复杂度分析

    (1)时间复杂度

    由于使用了两层for循环,因此时间复杂度为O(n^2)。

    (2)空间复杂度

    由于使用了带备忘录形式的动态规划,即借用了一个n*n大小的数组,因此空间复杂度也为O(n^2)。

    cs