Leetcode--LongestPalindromicString

两种思路:

第一种:将问题转化成求s和s逆串的最长连续公共子序列

最长连续公共子序列是在求最长公共子序列基础上增加了连续子序列的限定。先看下最长公共子序列:

假设A="a0,a1,...,am-1", B="b0,b1,...,bn-1", Z="z0,z1,...,zk-1"是A,B的最长公共子序列。

当am-1=bn-1可以分解成一个子问题求”a0,a1,...,am-2"以及"b0,b1,...,bn-2"的最长公共子序列

当am-1!=bn-1则分解成两个子问题

求”a0,a1,...,am-1"以及"b0,b1,...,bn-2"最长公共子序列

求”a0,a1,...,am-2"以及"b0,b1,...,bn-1"最长公共子序列

然后取两者中最长的子序列

问题可以变成如下递归:


可以通过动态规划构建c[i][j]矩阵解决这个问题。

求连续子序列可以直接构建二维矩阵c[][],c[i][j]=1表示s[i]=s'[j]这样最长的连续斜对角线就是最长连续字串。

public String longestPalindrome(String s) {
        length=s.length();
        int[][]lcs=new int[length][length];
        int max=-1;
        int index1=0;
        int index2=0;
        for(int i=0;i<length;i++){
            for(int j=0;j<length;j++){
                if(s.charAt(i)!=s.charAt(length-1-j))lcs[i][j]=0;
                else if(i==0||j==0){
                    lcs[i][j]=1;
                    if(lcs[i][j]>max){
                        index1=i;
                        index2=j;
                        max=lcs[i][j];
                    }
                }
                else {
                    lcs[i][j]=lcs[i-1][j-1]+1;
                    if(lcs[i][j]>max){
                        index1=i;
                        index2=j;
                        max=lcs[i][j];
                    }
                }
            }
        }
        int startindex=index1;
        while(index1>=0&&index2>=0){
            if(lcs[index1][index2]==0)break;
            index1--;
            index2--;
        }
        return s.substring(index1+1,startindex+1);
    }
第二种思路:

中心扩展,从中间位置向外扩展,求该位置扩展出的最长回文串。然后在上一层循环中遍历中心点的位置。

private int length=0;
    public String longestPalindrome(String s){
        if(s==null)return null;
        length=s.length();
        if(length==1)return s;
        String palindromic=s.substring(0,1);
        for(int i=0;i<length-1;i++){
            String tmp=findLongest(s,i,i);
                if(tmp.length()>palindromic.length())palindromic = tmp;
            tmp=findLongest(s,i,i+1);
                if(tmp.length()>palindromic.length())palindromic=tmp;
        }
        return palindromic;
    }
    private String findLongest(String s,int start,int end){
        while(start>=0&&end<length&&s.charAt(start)==s.charAt(end)){
            start--;
            end++;
        }
        return s.substring(start+1,end);
    }

最后发现第二种时间复杂度要小于第一种O(n2),因为第二种在第二层循环中并不需要扩展到n,很多时候会在中间停止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值