zoukankan      html  css  js  c++  java
  • [LeetCode] 5. 最长回文子串

    好难呜呜呜呜

    方法一:动态规划

    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][length];
            int maxLen=0;
            int maxEnd=0;
            for(int i=0;i<length;i++){
                for(int j=0;j<length;j++){
                    if(origin.charAt(i)==reverse.charAt(j)){
                        if(i==0||j==0){
                            arr[i][j]=1;
                        }else{
                            arr[i][j]=arr[i - 1][j - 1] + 1;
                        }
                    }
                /**********修改的地方*******************/
                if(arr[i][j]>maxLen){
                    int beforeRev=length-j-1;
                    if (beforeRev + arr[i][j] - 1 == i) { //判断下标是否对应
                        maxLen = arr[i][j];
                        maxEnd = i;
                    }
                }
            }
            }
        //return s.substring(maxEnd - maxLen + 1, maxEnd + 1);
        return s.substring(maxEnd-maxLen+1,maxEnd+1);
    }
    }

     方法二:相比于方法一 对arr数组进行了优化,把二维降为一维

    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;
                        }
                    }else{
                        arr[j]=0;
                    }
                    if(arr[j]>maxLen){
                        int beforeRev=length-j-1;
                        if (beforeRev + arr[j] - 1 == i) { //判断下标是否对应
                            maxLen = arr[j];
                            maxEnd = i;
                        }
                    }
                }
            }
        return s.substring(maxEnd-maxLen+1,maxEnd+1);
    }
    }

     没有什么实质性的提高哈。

    liweiwei1419 给出的动态规划的答案
    public class Solution {
    
        public String longestPalindrome(String s) {
            int len = s.length();
            if (len < 2) {
                return s;
            }
    
            boolean[][] dp = new boolean[len][len];
            for (int i = 0; i < len; i++) {
                Arrays.fill(dp[i], false);
            }
            // 初始化
            for (int i = 0; i < len; i++) {
                dp[i][i] = true;
            }
    
            char[] charArray = s.toCharArray();
            int maxLen = 1;
            int start = 0;
    
            for (int j = 1; j < len; j++) {
                for (int i = 0; i < j; i++) {
    
                    dp[i][j] = charArray[i] == charArray[j] && (j - i < 3 || dp[i + 1][j - 1]);
    
                    // 只要 dp[i][j] == true 成立,就表示子串 s[i, j] 是回文,此时记录回文长度和起始位置
                    if (dp[i][j]) {
                        int curLen = j - i + 1;
                        if (curLen > maxLen) {
                            maxLen = curLen;
                            start = i;
                        }
                    }
                }
            }
            return s.substring(start, start + maxLen);
        }
    }

    方法三:中心扩散

    public class Solution {
    
        public String longestPalindrome(String s) {
            int len = s.length();
            if (len < 2) {
                return s;
            }
            int maxLen = 1;
            String res = s.substring(0, 1);
            // 中心位置枚举到 len - 2 即可
            for (int i = 0; i < len - 1; i++) {
                String oddStr = centerSpread(s, i, i);
                String evenStr = centerSpread(s, i, i + 1);
                String maxLenStr = oddStr.length() > evenStr.length() ? oddStr : evenStr;
                if (maxLenStr.length() > maxLen) {
                    maxLen = maxLenStr.length();
                    res = maxLenStr;
                }
            }
            return res;
        }
    
        private String centerSpread(String s, int left, int right) {
            // left = right 的时候,此时回文中心是一个字符,回文串的长度是奇数
            // right = left + 1 的时候,此时回文中心是一个空隙,回文串的长度是偶数
            int len = s.length();
            int i = left;
            int j = right;
            while (i >= 0 && j < len) {
                if (s.charAt(i) == s.charAt(j)) {
                    i--;
                    j++;
                } else {
                    break;
                }
            }
            // 这里要小心,跳出 while 循环时,恰好满足 s.charAt(i) != s.charAt(j),因此不能取 i,不能取 j
            return s.substring(i + 1, j);
        }
    }

  • 相关阅读:
    python新手中常见疑惑及解答
    jquery中常见问题及解决办法小结
    javascript常用字符串函数和本地存储
    sublim3常用插件安装
    PHP-Yii执行流程分析(源码)
    PHP-流的概念与详细用法
    PHP-数据库长连接mysql_pconnect的细节
    PHP-"php://(类型)"访问各个输入/输出流以及全局变量$HTTP_RAW_POST_DATA讲解
    MySQL-LAST_INSERT_ID();使用注意事项
    SQL SERVER-时间戳(timestamp)与时间格式(datetime)互相转换
  • 原文地址:https://www.cnblogs.com/doyi111/p/12852933.html
Copyright © 2011-2022 走看看