• 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;
        }
    }
    
  • 相关阅读:
    OI中的小智慧
    洛谷 P2335 SDOI 2005 毒瘤 位图(也补上注释了)
    洛谷P4779 Dijkstra 模板
    洛谷 P1156 垃圾陷阱 谈论剪枝,非满分
    8/14考试 JWG
    一个好消息 JWG
    刷水题(一) JWG
    C语言运算符优先级从没像现在这样深刻体会
    cron 备忘
    CentOS
  • 原文地址:https://www.cnblogs.com/Asimple/p/16122399.html
Copyright © 2020-2023  润新知