LeetCode No5 最长回文子串

题目

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

示例 1:

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

示例 2:

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

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母组成

解题思路

中心扩展法

首先要知道回文串的定义,回文串是一个正读和反读都一样的字符串,比如 aba 或者 abba,既然正读与反读都是一样,那么这个串必然有一个中心对称点,我们可以利用这个中心点向两边扩展,找出最大的回文字串。遍历字符,把当前下标作为中心点,向两边进行扩展,直到左边的字符和右边的字符不一样,当然,就像给出的样例一样,回文串有可能是偶数个数也有可能是奇数个数,所以要以偶数回文串以及奇数回文串为目标求两个回文串,然后再取较大的那个。遍历完数组后,我们就可以得到最大回文字串了。

动态规划

这种回文字串的题目是DP里面的经典题目了,递推式也很简单,我们定义dp[len][len]数组,dp[i][j]=true表示从下标i至下标j的字串是回文串,而如果想要dp[i][j]为回文串,则必须要满足dp[i+1]dp[j-1]=true && s[i]==s[j]
同样我们再考虑下边界的情况,如果i至j,只有一个字符或者只有两个字符并且两个字符相等的时候,这个时候就找到了边界条件,也就可以完成这个DP了。

AC代码

中心扩展法

点击查看代码
class Solution {
    private String getStr(String s, int low, int high) {
        int len = s.length();
        while( low>=0 && high<len ) {
            if( s.charAt(low)==s.charAt(high) ) {
                low --;
                high ++;
            } else {
                break;
            }
        }
        return s.substring(low+1, high);
    }

    public String longestPalindrome(String s) {
        int len = s.length();
        if( len<2 ) {
            return s;
        }
        String res = "";
        for(int i=0; i<len-1; i++) {
            String odd = getStr(s, i, i);
            String even = getStr(s, i, i+1);
            String maxStr = odd.length()>even.length()?odd:even;
            if( maxStr.length() > res.length() ) {
                res = maxStr;
            }
        }
        return res;
    }
}

动态规划

点击查看代码
class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        // 空串和只有一个字符的字符串可以直接返回
        if( len < 2 ) {
            return s;
        }
        String res = s.substring(0, 1);
        boolean dp[][] = new boolean[len][len];
        for(int i=0; i<len; i++) {
            dp[i][i] = true;
        }
        char[] chars = s.toCharArray();
        // 枚举最长回文串的长度
        for(int k=2; k<=len; k++) {
            for(int i=0; i<len; i++) {
                int j = k + i - 1;
                if( j>=len ) {
                    break;
                }
                if( chars[i]!=chars[j] ){
                    dp[i][j] = false;
                    continue;
                }
                if( j-i<=2 ) {
                    dp[i][j] = true;
                } else {
                    dp[i][j] = dp[i+1][j-1];
                }
                if( dp[i][j] && res.length()<j-i+1 ) {
                    res = s.substring(i, j+1);
                }
            }
        }
        return res;
    }
}
posted @ 2022-04-09 16:15  Asimple  阅读(17)  评论(0编辑  收藏  举报