版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m940034240/article/details/88839328
tips:回文的意思是正着念和倒着念一样,如:上海自来水来自海上
问题
给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
解法
暴力解法:
class Solution {
public String longestPalindrome(String s) {
int length = s.length();
if(s.length() < 2){
return s;
}
int left=0; //当前最长回文子串的左下标
int right=0;//当前最长回文子串的右下标
int max = 1;//当前最长回文子串的长度
for(int i = 0 ; i < length; i++){
String str = s.substring(i,length);
int l2 = str.length();
if(l2<=max) break; //剩余长度小于当前最长回文子串的长度,结束校验
for(int j = 0; j < l2; j++){
if(j + 1<=max) continue;
String msg = str.substring(0,j+1);
boolean flag = true;//是否为回文字符串标识
int l3 = msg.length();
int size = l3/2;
for(int k = 0; k < size; k++){
if(msg.charAt(k)!=msg.charAt(l3-1-k)){
flag = false;
break;
}
}
if(flag){
if(l3>max){
max = l3;
left = i ;
right = i + j;
}
}
}
}
return s.substring(left, right + 1);
}
}
将所有可能截取到的字符串都判断一下是否为回文字符串,并选出最长的一种,这种解法结果虽然是正确的,但运行时间过长,占用内存过多,在LeetCode提交时有概率提示超时,故需进行优化
优化解法:
class Solution {
public String longestPalindrome(String s) {
int length = s.length();
if(s.length() < 2){
return s;
}
int left=0; //当前最长回文子串的左下标
int right=0;//当前最长回文子串的右下标
int max = 1;//当前最长回文子串的长度
int indexL,indexR;//中间部分字母连续相同的左右下标
for(int i=0; i < length; i++){
char c = s.charAt(i);
indexL = i;
indexR = i;
//先获取连续相同字符的左下标
for(int k = 1; k <= i; k++){
if(s.charAt(i-k)!=c){
indexL = i - k + 1;
break;
}else if(k == i){
indexL = i - k;
}
}
//获取连续相同字符的右下标
for(int k = 1; k <= length - 1 - i; k++){
if(s.charAt(i+k)!=c){
indexR = i + k - 1;
break;
}else if(k == length - 1 - i){
indexR = i + k;
}
}
int z = indexR - indexL + 1;
if(z>max){
max = z;
left = indexL;
right = indexR;
}
//然后依次判断左右两边的字符是否相同,直到出现不同或超出范围为止
for(int k = 1; k <= indexL; k++){
if(indexL- k<0 || indexR+k>=length) break;
char leftC = s.charAt(indexL- k);
char rightC = s.charAt(indexR + k);
if(leftC!=rightC){
int t = indexR + k - 1 - (indexL - k + 1) + 1;
if(max < t){
max = t;
left = indexL - k + 1;
right = indexR + k - 1;
}
break;
}else if(indexL - k == 0 || indexR + k == length-1){
int t = indexR + k - (indexL - k) + 1;
if(max < t){
max = t;
left = indexL - k;
right = indexR + k;
}
break;
}
}
}
return s.substring(left, right + 1);
}
}
优化后效果