LeetCode算法题之5:Longest Palindromic Substring

LeetCode之5:Longest Palindromic Substring

问题描述:

在这里插入图片描述

查找一个字符串的最长对称子序列。本文解法参考了[LeetCode] Longest Palindromic Substring 最长回文子串

问题的陷阱与难点:

  1. 能否在较短时间内理清逻辑,快速写出代码。
  2. 普通的向两边扩展查找最长字串的方法比较好想,但是存在较多重复操作。dp的解法比较难想出来。

缺陷代码分析(41.98%)

/**
 * @program: xiaolajiao001
 * @description: Longest Palindromic Substring
 * @author: yi ao
 * @create: 2019-02-20 16:32
 */
public class LeetCode5 {
  int max = 0;
  int left = 0,right = 0;

  public String longestPalindrome(String s) {
    if (s == null || s.length() == 0) {
      return s;
    }
    int length = s.length();
    boolean [][] dp = new boolean[length][length];
    for (int i = 0; i < length; i++) {
      for (int j = 0; j < i; j++) {
        dp[j][i] = s.charAt(i) == s.charAt(j) && (i - j < 2 || dp[j + 1][i - 1] == true);
        if (dp[j][i] == true && i - j + 1 > max) {
          max = i - j + 1;
          left = j;
          right = i;
        }
      }
      dp[i][i] = true;
    }
    return s.substring(left, right + 1);
  }
}

**这道题主要考察的是思路,很容易在遍历的过程中产生重复的操作,所以如何能让之前判断好的结果辅助运用到后面的子串,这是典型的动态规划(dp)思想. **

思路

既然要用dp,肯定需要一个结构存储已经计算完毕的结果。

由于该题是求最长连续子序列,所有可能的子序列的个数是length2. 所以使用二维数组保存是最好的。

dp的核心就是前人栽树,后人乘凉。该题该怎样设计dp公式?

很容易想到的是,一个字符肯定是对称的,两个相等的字符也是对称的。除此之外,三个或三个以上的字符串则必须两端的两个字符相等,才有可能是对称的,因此,dp公式就得到了,假设array二维数组保存的是结果, i , j 分别代表字符串的左右边界下标,s代表的原始字符串:

二维数组 取值 条件
array[i, j] true if i==j
array[i, j] s[i] == s[j] if i + 1 = j
array[i, j] s[i] == s[j] && array[i+1][j-1] if i + 1 < j

如此以来,如果我们进行两层循环遍历,便可以像99乘法表那样,逐渐将从最小的字符串到最大的字符串的匹配结果得到。时间复杂度是O(n2)。

  1. 能不能将时间复杂度降低到小于O(n2)?

猜你喜欢

转载自blog.csdn.net/veatheroe/article/details/87856367