题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
题解:
- 暴力解法
思路:遍历所有字符串,判断是否为回文,找出最长字串
public String longestPalindrome(String s) {
int len = s.length();
for (int i = len; i > 0; i--) {
for (int j = 0; j <= len - i; j++) {
String substring = s.substring(j, i + j);
if (isPalindrome(substring)) {
return substring;
}
}
}
return s;
}
private boolean isPalindrome(String str) {
int len = str.length();
for (int i = 0; i < len / 2; i++) {
if (str.charAt(i) != str.charAt(len - i - 1)) {
return false;
}
}
return true;
}
两个for循环,加上一个isPalindrome函数for循环,时间复杂度为O(n³)。
- 动态规划
相比于暴力解法,就是少了些判断。思路为:遍历字符串,记住之前判断的结果,再扩大字符串进行判断
public String longestPalindrome(String s) {
int length = s.length();
boolean[][] dp = new boolean[length][length];
int maxSize = 0;
int beginIndex = 0;
for (int i = length - 1; i >= 0; i--) { //外圈判断,动态规划从右边开始,从小范围到大范围
for (int j = i; j < length; j++) { //内圈判断
dp[i][j] = s.charAt(i) == s.charAt(j);
if (i + 1 <= j - 1) {
dp[i][j] = dp[i + 1][j - 1] && dp[i][j];
}
if (j - i + 1 >= maxSize && dp[i][j]) {
maxSize = j - i + 1;
beginIndex = i;
}
}
}
return s.substring(beginIndex, beginIndex + maxSize);
}
时间复杂度为O(n²),空间复杂度为O(n²)。
- Manacher’s Algorithm 马拉车算法
待补充