Leetcode刷题之旅--5. 最长回文子串

题目描述:
在这里插入图片描述

思路:一开始想的是用两个字符串最长公共子串来做,一个字串是给定的,另一个字串是给定的字串的逆序。但是最后解答错误。[“aacdefcaa”]这个的最长回文子串是aa,如果按最长公共子串来做得到的是acc。
先附上按最长公共字串做法的代码:

class Solution {
    public static void main(String[] args) {
        String s="abb";
        System.out.println(new Solution().longestPalindrome(s));
    }
    public String longestPalindrome(String s) {
        if (s.equals(""))return "";
        int len=s.length();
        int [][] ch=new int [len][len];
        int maxlength=1;
        int maxx=0;
        String str="";
        for (int i=0;i<len;i++){
            if (s.charAt(i)==s.charAt(len-1)){
                ch[0][i]=1;
            }
            if (s.charAt(len-i-1)==s.charAt(0)){
                ch[i][0]=1;
            }
        }
        for (int i=1;i<len;i++){
            for (int j = 1; j < len; j++) {
                if (s.charAt(len-i-1)==s.charAt(j)){
                    ch[i][j]=ch[i-1][j-1]+1;
                    if (ch[i][j]>maxlength){
                        maxlength=ch[i][j];
                        maxx=j;
                    }
                }
            }
        }
        for (int i=maxx-(maxlength-1);i<=maxx;i++){
            str=str+s.charAt(i);
        }
        return str;
    }
}

本来以为这个方法没有办法解出来了,但是看了下评论区,可以在长度增加时候进行一个是否是回文子串的判定。附上作者的做法:
在这里插入图片描述
作者的代码:

class Solution {
    public String longestPalindrome(String s) {
        if (s.equals(""))
            return "";
        String origin = s;
        String reverse = new StringBuffer(s).reverse().toString();
        int length = s.length();
        int[] arr = new int[length];
        int maxLen = 0;
        int maxEnd = 0;
        for (int i = 0; i < length; i++)
        /**************修改的地方***************************/
            for (int j = length - 1; j >= 0; j--) {
                /**************************************************/
                if (origin.charAt(i) == reverse.charAt(j)) {
                    if (i == 0 || j == 0) {
                        arr[j] = 1;
                    } else {
                        arr[j] = arr[j - 1] + 1;
                    }
                    /**************修改的地方***************************/
                    //之前二维数组,每次用的是不同的列,所以不用置 0 。
                } else {
                    arr[j] = 0;
                }
                /**************************************************/
                if (arr[j] > maxLen) {
                    int beforeRev = length - 1 - j;
                    if (beforeRev + arr[j] - 1 == i) {
                        maxLen = arr[j];
                        maxEnd = i;
                    }

                }
            }
        return s.substring(maxEnd - maxLen + 1, maxEnd + 1);
    }
}

最后看一下官方的解法:
1.暴力法:得到所有的子串并同时判定子串是否是回文子串
在这里插入图片描述
时间复杂度O(n^3)
空间复杂度O(1)
2.中心散列法
有些类似暴力法,但是时间复杂度有所改善。首先一个回文子串长度可以是奇数或偶数两种情况,分别将给定的字符串的每个字符当作回文子串的中心,之后判定每个字符为中心的回文子串的最长长度,得到结果。
在这里插入图片描述
时间复杂度O(n^2)
空间复杂度O(1)

3.动态规划
动态规划需要判定的情况比较复杂
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以此类推
4.Manacher算法(专用来查找最长回文子串)
emmm算法比较复杂,暂时放弃。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值