题目描述
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
示例 3:
输入:s = “a”
输出:“a”
示例 4:
输入:s = “ac”
输出:“a”
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
解题思路(一):暴力解法
列举所有子串,空间O(1),双重遍历,还有一层判断是否是回文,时间O(n3),
// 暴力解法
public String longestPalindrome(String s) {
char[] chars = s.toCharArray();
//长度小于等于1,直接返回
if (s.length() <= 1) {
return s;
}
int len = chars.length - 1;
String result = "";
tag: //跳出多重循环的标签
for (int i = 0; i < chars.length; i++) {
for (int j = len; j > i; j--) {//逆序遍历,找到就跳出
if(result.length()>len+1-i){//剩下长度小于已有回文字符串
break tag;//跳出全部循环
}
if (ifPalindrome(chars, i, j)) {
if (result.length() < j + 1-i) {//已有回文小于最新回文串长度
result = s.substring(i, j + 1);
}
break;//找到回文串,换下一个i值
}
}
}
if (result.length() < 1) {
result = String.valueOf(chars[0]);
}
return result;
}
public boolean ifPalindrome(char[] chs, int begin, int end) {
if (begin == end) {
return true;
} else if (begin + 1 == end) {
return chs[begin] == chs[end];
} else if (chs[begin] == chs[end]) {
return ifPalindrome(chs, begin + 1, end - 1);
}
return false;
}
解题思路(二):倒置,然后找最长公共子串
时间复杂度 O(n²)。
空间复杂度降为 O(n)O(n)。
public String longestPalindrome(String s) {
if (s.equals(""))
return "";
String origin = s;
String reverse = new StringBuffer(s).reverse().toString();
int length = s.length();
int[] arr = new int[length];
int maxLen = 0;
int maxEnd = 0;
for (int i = 0; i < length; i++)
for (int j = length - 1; j >= 0; j--) {
if (origin.charAt(i) == reverse.charAt(j)) {
if (i == 0 || j == 0) {
arr[j] = 1;
} else {
arr[j] = arr[j - 1] + 1;
}
} else {
arr[j] = 0;
}
if (arr[j] > maxLen) {
int beforeRev = length - 1 - j;
if (beforeRev + arr[j] - 1 == i) {
maxLen = arr[j];
maxEnd = i;
}
}
}
return s.substring(maxEnd - maxLen + 1, maxEnd + 1);
}