给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
1、暴力解法
遍历所有的子串,并判断每一个子串是否为回文串,最后即可得到最长的回文子串。
class Solution {
public String longestPalindrome(String s) {
int length = s.length();
int maxLength = 0;
String res = "";
for(int subLength = 1; subLength <= length; subLength++){
for(int index = 0; index + subLength <= length; index++){
String subStr = s.substring(index, index + subLength);
if(isPalindrome(subStr)){
if(subStr.length() > maxLength){
maxLength = subStr.length();
res = "" + subStr;
}
}
}
}
return res;
}
public boolean isPalindrome(String s){
int length = s.length();
int left = 0;
int right = length - 1;
while(left <= right){
if(s.charAt(left) != s.charAt(right)){
return false;
}
left++;
right--;
}
return true;
}
}
两层for循环进行两次遍历,判断回文串也要进行一次遍历,则时间复杂度达到了O(n³),直接提交会超时。但是参考官方题解,暴力解法也是能通过的。在以上解法中每判断一次回文子串都需要截取一次字符串,会有额外的性能消耗,则不再截取字符串,只记录最长回文子串的起始位置和长度,最后返回的时候再截取子串。当字符串长度为1时不需要判断直接返回即可。进行剪枝操作后可勉强通过。
//执行用时:2850 ms
class Solution {
public String longestPalindrome(String s) {
int length = s.length();
if(length < 2){
return s;
}
int maxLength = 1;
int resLeft = 0;
for(int subLength = 2; subLength <= length; subLength++){
for(int index = 0; index < length - subLength + 1; index++){
if(isPalindrome(s, index, index + subLength - 1)){
if(subLength > maxLength){
maxLength = subLength;
resLeft = index;
}
}
}
}
return s.substring(resLeft, resLeft + maxLength);
}
public boolean isPalindrome(String s, int left, int right){
int indexL = left;
int indexR = right;
while(indexL <= indexR){
if(s.charAt(indexL) != s.charAt(indexR)){
return false;
}
indexL++;
indexR--;
}
return true;
}
}
时间复杂度:O(n³)
空间复杂度:O(1),仅消耗常数空间
网友评论