Leecode5:最长回文子串

题目描述:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
方法一:求最长公共子串。(动态规划)

我们知道一个回文串不论正着读还是逆着读都是一样的,我们根据这个特征来动态规划求解。现在问题转化成了两个字符串的最长公共子串的求解。最后我们只需要附加一些判断条件就可以知道这是不是个回文串了。
我们需要建立一个二维数组,arr[len][len],其中arr[i][j]=arr[i-1][j-1]+1。附加判断条件: 我们现在作比较的两个子串实际上是不是同一个,具体什么意思看下文。
代码如下:

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

附加判断条件
以字符串caba和abc34cba为例

  • 时间复杂度O(n2)
  • 空间复杂度O(n2)
方法二:扩展中心法

所以中心位置共n+n-1=2n-1个

public String longestPalindrome(String s) {
    
    
    if (s == null || s.length() < 1) return "";
    int start = 0, end = 0;
    for (int i = 0; i < s.length(); i++) {
    
    
        int len1 = expandAroundCenter(s, i, i);
        int len2 = expandAroundCenter(s, i, i + 1);
        int len = Math.max(len1, len2);
        if (len >=( end - start+1) {
    
    
            start = i - (len - 1) / 2;
            end = i + len / 2;
        }
    }
    return s.substring(start, end + 1);
}

private int expandAroundCenter(String s, int left, int right) {
    
    
    int L = left, R = right;
    while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
    
    
        L--;
        R++;
    }
    return R - L - 1;  //R-L+1-2。就算不符合循环条件,l和R在之前也做了相应处理
}
  • 时间复杂度O(n2)
  • 空间复杂度O(1)

猜你喜欢

转载自blog.csdn.net/qq_43406565/article/details/105179556