最长回文字符串问题,解决方案

 1.暴力匹配法+剪枝操作

    //从当前位置出发,从后向前找
    //找的位置跨度不能小于maxLength 因为小于它的话,即使是,也不是最长的了
    //此定义为暴力匹配法,虽然经剪枝操作,时间复杂度也仍为n^3
    public String longestPalindrome(String s) {
        if(s==null||s.length()==0){
            return "";
        }
        HashMap<Integer,String> hash=new HashMap<>();
        int maxLength=1;
        hash.put(1,s.charAt(0)+"");
        for (int i = 0; i < s.length()-maxLength; i++) {
            for (int j = s.length()-1; j>i; j--) {
                if(j-i+1<=maxLength){//当前说明跨度已经不大于最大长度了,也就没有必要在继续了
                    break;
                }
               if(s.charAt(j)==s.charAt(i)){
                   if(isRoundStr(s,i,j)){
                       maxLength=j-i+1;
                       hash.put(maxLength,s.substring(i,j+1));
                       break;
                   }
               }
            }
        }
        return hash.get(maxLength);
    }
    private boolean isRoundStr(String s,int leftIndex,int rightIndex){
        while (leftIndex<rightIndex){
            if(s.charAt(leftIndex)!=s.charAt(rightIndex)){
                return false;
            }
            leftIndex++;
            rightIndex--;
        }
        return true;
    }

2.中心法

 public String longestPalindrome(String s){
        if(s.length()<2){
            return s;
        }
        int begin=0,maxLength=1;
        int len1,len2,len;
        for (int i = 0; i < s.length()-1; i++) {
            //奇数个,与,偶数个
            len1=expendStr(s,i,i);
            len2=expendStr(s,i,i+1);
            len=len1>len2?len1:len2;
            if(len>maxLength){
                maxLength=len;
                begin=i-(maxLength-1)/2;
            }
        }
        return s.substring(begin,begin+maxLength);
    }
    private int expendStr(String s,int left,int right){
        while (left>=0&&right<=s.length()-1){
            if(s.charAt(left)==s.charAt(right)){
                left--;
                right++;
            }else {
                break;
            }
        }
        //当前到达的位置是不匹配的位置 right-left+1-2
        return right-left-1;
    }

3.动态规划

 就是按照递归的思路,但是转换成空间来记录的形式完成,记住!这就是动态规划

 //动态规划,时间复杂度也是n^2
    //a b c b a ;  dp[i][j]=s[i]==s[j]&&(dp[i+1][j-1]||j-i<=2)
    public String longestPalindrome3(String s){
        if(s.length()<2){
            return s;
        }
        int begin=0,maxLength=1;
        //i是左边索引,j是右边索引,由此可见我们构建的使用的是上三角形
        boolean[][] dp=new boolean[s.length()][s.length()];
        //对角线全为true
        for (int i = 0; i < s.length(); i++) {
            dp[i][i]=true;
        }
        //由公式dp[i][j]=s[i]==s[j]&&(dp[i+1][j-1]||j-i<=2)知本次的我们需要使用本节点的左下角的判断,因此我们一列一列构架
        //中间对角线位置及dp[0][0] dp[1][1]...这些位置值都为true
        for (int j = 1; j < dp.length; j++) {//j代表列,i代表行
            for (int i = 0; i < j; i++) {
                if(s.charAt(i)==s.charAt(j)){
                    if(j-i<=2||dp[i+1][j-1]){
                        dp[i][j]=true;
                    }
                }
                if(dp[i][j]&&j-i+1>maxLength){
                    begin=i;
                    maxLength=j-i+1;
                }
            }
        }
        return s.substring(begin,begin+maxLength);
    }

猜你喜欢

转载自www.cnblogs.com/ningxinjie/p/13167335.html
今日推荐