寻找最长回文字符串扩展及优化

中心扩展法

从字符串中间向两边扩散寻找最长的回文字符串。分为两种情况字符串长度位奇数和偶数,比如 aba奇数,从下标为1处开始向两边寻找,可以找到最大回文;abba偶数从下标为1和2开始寻找,可以找到最大回文。
代码实现:

public class Main{
	// 输出最后一个最大的回文串
	private static List<String> getLargeLength(String str) {
		String res = "";
        for (int i = 0; i < str.length(); i++) {
            String palStr = getPalStr(str, i, i);
            String palStr1 = getPalStr(str, i, i + 1);
            palStr = palStr.length() > palStr1.length() ? palStr : palStr1;

            if (res.length() <= palStr.length()) {
                res = palStr;
            }
        }
        return res;
    }
    
	// 要求输出所有的最大回文串
	private static List<String> getLargeLength(String str) {
		List<String> list = new LinkedList<>();
        String res = "";
        for (int i = 0; i < str.length(); i++) {
        	// 找出奇数的回文串
            String palStr = getPalStr(str, i, i);
            // 找出偶数的回文串
            String palStr1 = getPalStr(str, i, i + 1);
            palStr = palStr.length() > palStr1.length() ? palStr : palStr1;

			// 如果要求输出所有的最大回文串,添加到list
            if (res.length() <= palStr.length()) {
                if (res.length() < palStr.length()) {
                    list.clear();
                }
                res = palStr;
                list.add(res);
            }
        }
        return list;
    }
    
	private String getPalStr(String str, int left, int right) {
        while (left >= 0 && right < str.length()
                && str.charAt(left) == str.charAt(right)) {
            left--;
            right++;
        }
        return str.substring(left + 1, right);
    }
}
动态规划法

整理自:https://blog.csdn.net/u013309870/article/details/70742315

时间复杂度O(n^2), 空间复杂度O(n^2), 如果用f[i][j]保存子串从i 到j是否是回文子串,那么在求f[i][j] 的时候如果j-i>=2时, 如果 f[i][j] 为回文,那么f[i+1][j-1],也一定为回文。否则f[i][j]不为回文。如下图:
在这里插入图片描述
因此可得到动态规划的递归方程:
在这里插入图片描述
代码实现

public static String palindrome1(String str) {
      if (str == null || str.length() == 0) {
          return "";
      }

      char chs[] = str.toCharArray();
      int maxLen = 1;
      int start = 0;
      boolean isPal[][] = new boolean[chs.length][chs.length];

      for (int j = 0; j < str.length(); j++) {
          for (int i = 0; i <= j; i++) {
              if (j - i < 2) {
                  isPal[i][j] = (chs[i] == chs[j]);
              } else {
                  // 长度大于2时,isPal[i][j]如果是回文,那么isPal[i+1][j-1]一定是回文
                  isPal[i][j] = (isPal[i + 1][j - 1] && chs[i] == chs[j]);
              }

			  // 如果[i][j]是回文,并且长度大于maxLen则更新最大长度
              if (isPal[i][j] && (maxLen < j - i + 1)) {
                  maxLen = j-i+1;
                  start = i;
              }
          }
      }
      return str.substring(start, start+maxLen);
  }

中心扩展法和动态规划对比,时间复杂度一样O(n^2), 但是动态规划空间复杂度至少要 O(N^2) 来存储 DP table。所以这道题中心扩展优于动态规划

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值