package com.example.lettcode.dynamicprogramming;
import java.util.Arrays;
/**
* @Class LongestPalindrome
* @Description 5 最长回文子串
* 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
* <p>
* 示例 1:
* 输入: "babad"
* 输出: "bab"
* 注意: "aba" 也是一个有效答案。
* <p>
* 示例 2:
* 输入: "cbbd"
* 输出: "bb"
* @Author
* @Date 2020/8/5
**/
public class LongestPalindrome {
/**
* 动态规划: 解法和leetcode 647 回文子串 类似
* (1)dp[i][j]表示从s[i..j]是否为回文子串
* (2)状态转换:
* i:当j-i<3 并且s[i]=s[j]时,即类似abs时,也是回文串
* ii: 当s[i]=s[j]并且s[i+1...j-1]是回文串时,s[i...j]是回文串
*/
public static String longestPalindrome(String s) {
if (s == null || s.length() == 0) return "";
boolean[][] dp = new boolean[s.length()][s.length()];
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j < s.length(); j++) {
dp[i][j] = false;
}
dp[i][i] = true;
}
for (int i = s.length() - 2; i >= 0; i--) {
for (int j = i + 1; j < s.length(); j++) {
dp[i][j] = s.charAt(i) == s.charAt(j)
//小于3是因为aba一定是回文
&& (j - i < 3 || dp[i + 1][j - 1] == true);
// dp[i][j]为True,并且需要更新的话
if (dp[i][j] && end - start < j - i) {
end = j;
start = i;
}
}
}
return s.substring(start, end + 1);
}
public static void main(String[] args) {
String s = "babad";
String ans = longestPalindrome(s);
System.out.println("LongestPalindrome demo01 resul:" + ans);
s = "cbbd";
ans = longestPalindrome(s);
System.out.println("LongestPalindrome demo02 resul:" + ans);
}
}