子序列6.最长回文子串

中心扩展

这个题是回文子串,下一个题为回文子序列,他们的核心都在于从中间向两边扩展。应该使用双指针来判断现在两头的字母是否相同。
但中心可能是一个也可能是两个。在遍历的过程中应该找是以i和i+1或者是单独一个i为中心的最长回文字符串,然后这俩和res比较,哪个大则选哪个。找最大回文字符串的方法就是传入俩指针,让其不断扩张最后返回最大的String。

class Solution {
    public String longestPalindrome(String s) {
        if(s==null || s.length()==0||s.length()==1){
            return s;
        }
        String res="";
        for(int i=0;i<s.length();i++){
            String str1=core(s,i,i);
            String str2=core(s,i,i+1);
            res=str1.length()>res.length()?str1:res;
            res=str2.length()>res.length()?str2:res;
        }
        return res;
    }
    public String core(String s,int i,int j){
        while(i>=0 && j<s.length() && s.charAt(i)==s.charAt(j)){
            i--;
            j++;
        }
        return s.substring(i+1,j);
    }
}

首先在回文子串中定义dp[i][j]是数组i到j是否是一个回文串,为什么设置为boolean类型呢,因为要求的是一个字符串,所以只要记下哪个为true的长度最大即可。如果此时知道了dp[i+1][j-1],则s[i]和[j]如果相等,则dp[i][j]=dp[i+1][j-1],如果不相等,则为false,如果j-i小于3,直接可认为是true。所以其实dp[I][j]可以由dp[i+1][j-1]得到,i是小于j的,所以填表的上半部分即可,对角线知道了,还要直到左下的值。所以就和下面的题一样,从最后一个,最后一行开始遍历吧。

动态规划

class Solution {
    public String longestPalindrome(String s) {
        if(s==null || s.length()==0||s.length()==1){
            return s;
        }
        char[] chars=s.toCharArray();
        boolean[][]  dp=new boolean[chars.length][chars.length]; 
        for(int i=0;i<chars.length;i++){
            dp[i][i]=true;
        }
        int max=0;
        int start=0;
        int end=0;
        for(int i=s.length()-2;i>=0;i--){
            for(int j=s.length()-1;j>i;j--){
                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>max){
                    max=j-i+1;
                    start=i;
                    end=j;
                }
            }
        }
        return s.substring(start,end+1);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值