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

    LeetCode 5 最长回文子串

    问题描述:
    给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

    动态规划

    执行用时:209 ms, 在所有 Java 提交中击败了12.42%的用户
    内存消耗:50.1 MB, 在所有 Java 提交中击败了5.01%的用户

    class Solution{
        //动态规划
        //dp[i][j]表示str[i, j]范围内最长回文子串长度, j>=i
        //dp[i][j]与dp[i+1][j]、dp[i][j-1]、dp[i+1][j-1]有关
        //1. 若str[i]==str[j] and dp[i+1][j-1]==j-(i+1)
        //      dp[i][j] = dp[i+1][j-1]+2
        //2. 其它情况
        //      dp[i][j] = max{dp[i+1][j], dp[i][j-1], dp[i+1][j-1]}
        //初始: dp[i][i] = 1
        public String longestPalindrome(String s) {
            if(s==null || s.length()<=1) {
                return s;
            }
    
            int[][] dp = new int[s.length()][s.length()];
            //状态初始化
            for(int i=0; i<s.length(); i++) {
                dp[i][i] = 1;
            }
            //状态递推O(N2)
            int left = 0, right = 0;
            //遍历方式存在问题(保证后有效性)
            for(int j=0; j<s.length(); j++) {
                for(int i=0; i<=j; i++) {
                    if(i==j) {
                        continue;
                    }
                    //考虑奇对称、偶对称两种情况下的初始情况(两个值、三个值)
                    if(s.charAt(i)==s.charAt(j) 
                    && (i+1==j || dp[i+1][j-1]==(j-i-1))) {
                        dp[i][j] = j+1-i;
                    }
                    else {
                        dp[i][j] = Math.max(
                            i+1==j? 0: dp[i+1][j-1], 
                            Math.max(dp[i+1][j], dp[i][j-1])
                        );
                    }
                    //记录字符串起始坐标
                    if(right+1-left < dp[i][j] && dp[i][j]==j+1-i) {
                        left = i;
                        right = j;
                    }
                }
            }
            return s.substring(left, right+1);
        }
    }
    

    暴力优化: 中心扩散

    执行用时:58 ms, 在所有 Java 提交中击败了59.81%的用户
    内存消耗:37.6 MB, 在所有 Java 提交中击败了67.40%的用户

    //问题描述:在给定字符串中找到最长的回文“子串”,回文子串的定义为:字符串对称分布,即从左到右、从右到左遍历输出一致
    /**动态规划:
     * 状态转移:Sub[i,j]表示arr[i]..arr[j]组成的子串
     *          若Sub[i,j]是回文串,则需要满足:Sub[i+1,j-1]是回文串,且arr[i] == arr[j]
     * 递推:找到一个最小的回文串,例如"aa"、"aba",由该回文串向外扩展
     * */
     //O(N2/2)
    class Solution{
        public String longestPalindrome(String s) {
            if(s.length()<=1) return s;
            if(s.length()==2) return (s.charAt(0)==s.charAt(1))?s:s.charAt(0)+"";
    
            int maxLen = 1, minLeft = 0, maxRight = 0;
            //1、找到一个最小的回文串(由第二个向倒数第二个寻找)
            //2、由最小回文串向两边扩展,找到一个最长的回文串
            //时间复杂度:O(N2)
            for(int i=1;i<s.length()-1;i++){
                //偶数
                if(s.charAt(i)==s.charAt(i-1)){
                    int currLen = searchPalindrome(s, i-1, i);
                    if(maxLen < currLen){
                        maxLen = currLen;
                        minLeft = i - currLen/2;
                        maxRight = i-1 + currLen/2;
                    }
                }
                if(s.charAt(i) == s.charAt(i+1)){
                    int currLen = searchPalindrome(s, i, i+1);
                    if(maxLen < currLen){
                        maxLen = currLen;
                        minLeft = i+1 - currLen/2;
                        maxRight = i + currLen/2;
                    }
                }
                //奇数
                if(s.charAt(i-1)==s.charAt(i+1)){
                    int currLen = searchPalindrome(s, i-1, i+1);
                    if(maxLen < currLen){
                        maxLen = currLen;
                        minLeft = i - currLen/2;
                        maxRight = i + currLen/2;
                    }
                }
            }
    
            System.out.println("maxLen="+maxLen);
            return s.substring(minLeft, maxRight+1);
        }
    
        public int searchPalindrome(String s, int i, int j){
            int maxLen = j-i+1;
            i--;j++;
            while(i>=0 && j<s.length()){
                if(s.charAt(i) != s.charAt(j)) break;
                maxLen += 2;
                i--;j++;
            }
            return maxLen;
        }
    
    }
    
  • 相关阅读:
    找出有序数组中绝对值最小的数
    warning:deprecated conversion from string constant to 'char *' 解决方案
    Wordnet 与 Hownet 比较
    心灵鸡汤
    冒泡排序
    .NET加密配置文件connectionStrings节点
    C#基础知识之方法重载总结
    [C#]工具类—FTP上传下载
    C#基础知识-对象初始化顺序
    自定义Dictionary支持线程安全
  • 原文地址:https://www.cnblogs.com/CodeSPA/p/13693612.html
Copyright © 2011-2022 走看看