给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
示例 3:
输入:s = “a” 输出:“a”
示例 4:
输入:s = “ac” 输出:“a”
//方法一:中心扩展法
基本思路:
从某个元素开始,左右两边探索是否符合回文数并返回回文数的长度,比较并保存最长起始坐标和长度;
注意:回文数奇偶情况
时间复杂度:O(N^2) 空间复杂度: O(1)
public String longestPalindrome(String s) {
if (s == null || s.length() < 2) return s;
int resIdx = 0, resLen = 1;
for (int idx = 0; idx < s.length() - 1; idx++) {
//奇数最长回文长度
int len1 = longestLen(s, idx, idx);
//偶数最长回文长度
int len2 = longestLen(s, idx, idx + 1);
//当回文子串大于1的时候,将回文子串长度赋值给reslen,然后用回文中心的点减去回文子串的一半,就是回文数开始的点的下标。
if (len1 > resLen) {
resLen = len1;
resIdx = idx - resLen / 2;
}
if (len2 > resLen) {
resLen = len2;
resIdx = idx - (resLen / 2 - 1);
}
}
//从回文数的第一个下标开始,到回文数结束的子串
return s.substring(resIdx, resIdx + resLen);
}
//左右探索最长回文子串长度
private int longestLen(String s, int left, int right) {
while (left >= 0 && right < s.length()) {
if (s.charAt(left) != s.charAt(right)) break;
left--;
right++;
}
return right - left - 1;
}
/**
* 动态规划
* 不太懂,学习动态规划再看看
*/
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() <= 1) {
return s;
}
int start = 0, end = 0;
boolean[][] flag = new boolean[s.length()][s.length()];
for (int j = 0; j < s.length(); j++) {
for (int i = 0; i <= j; i++) {
if (i == j || (s.charAt(i) == s.charAt(j) && flag[i + 1][j - 1]) || (s.charAt(i) == s.charAt(j) && i + 1 == j)) {
flag[i][j] = true;
//判断是否更新
if (j - i > end - start) {
start = i;
end = j;
}
}
}
}
return s.substring(start, end + 1);
}
}
方法三:利用栈