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


     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);
        }
  • 相关阅读:
    Linux中-POSIX 线程详解
    sql server 2008如何导入mdf,ldf文件
    div浏览器兼容问题
    桥(Bridge)模式
    JSTL核心标签
    filter中的dispatcher解析
    synchronized探究
    最全设计模式(转载)
    面试题总结
    企业为什么要去竞争?
  • 原文地址:https://www.cnblogs.com/ningxinjie/p/13167335.html
Copyright © 2020-2023  润新知