题目描述:
给你一个字符串 s
,找到 s
中最长的回文子串。
注:回文串就是正着读和反着读是一样的,例如:上海自来水来自海上。包括我们之前学习C语言的时候,也有回文数,如:12344321。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
解法一:暴力破解法。
思路:暴力破解法很好理解,通过两层for循环来判断回文数,外层for循环遍历字符串,内层for循环从外层for循环的下一个位置开始逐一判断。最终得到最长的回文子串。暴力破解法的时间复杂度为O(n^2)。
代码:
public class Solution {
public String longestPalindrome(String s) {
//如果字符串长度小于2,直接返回
if ( s.length() < 2) {
return s;
}
//最长回文子串的长度
int max = 0;
int begin = 0;
// s.charAt(i) 每次都会检查数组下标越界,因此先转换成字符数组
char[] charArray = s.toCharArray();
// 枚举所有长度大于 1 的子串 charArray[i..j]
for (int i = 0; i < s.length() - 1; i++) {
for (int j = i + 1; j < s.length(); j++) {
if (j - i + 1 > max && isPalinedrome(charArray, i, j)) {
max = j - i + 1;
begin = i;
}
}
}
return s.substring(begin, begin + max);
}
/**
* 判断子串是否为回文串
*/
public boolean isPalinedrome(char[] charArray, int left, int right) {
while (left < right) {
if (charArray[left] != charArray[right]) {
return false;
}
left++;
right--;
}
return true;
}
}
解法二:中心扩散法。
思路:在遍历字符串的时候,对于每一个字符,以当前字符为中心向两边扩散,从而查找得到最长的回文子串。这里有一个很重要的问题在于:回文串的长度为奇数和偶数的时候,其中兴位置时不同的,所以其判断方式也会有所变化。以示例1和示例2为例,如下图:
因此,针对于上述的奇数和偶数两种情况,采用不同的方式去处理,如下:
(1)如果为奇数,则由i位置向两边开始扩散。
(2)如果为偶数,则由i和i+1分别向左右开始扩散。
代码:
public class Solution {
public String longestPalindrome(String s) {
//如果字符串长度小于2,直接返回
if(s.length() < 2){
return s;
}
//回文子串的长度
int max = 0;
//数组:res[0]代表起始位置,res[1]代表终止位置
int[] res = new int[2];
//字符串长度为奇数时,从i开始向两边扩散。对比对应位置的值。
//字符串长度为偶数时,从i开始向左扩散,从i+1开始向右扩散。
for(int i=0; i < s.length()-1; i++){
int[] odd = getPosAndLen(s, i, i);
int[] even = getPosAndLen(s, i, i+1);
//判断回文子串的长度。
int[] maxArr = odd[1] > even[1] ? odd : even;
//如果长度大于max,则更新max和res
if(maxArr[1] > max){
max = maxArr[1];
res = maxArr;
}
}
return s.substring(res[0], res[0] + res[1]);
}
public int[] getPosAndLen(String s, int left, int right){
//从left和right开始比较对应位置的值是否相同
while(left >= 0 && right < s.length()){
if(s.charAt(left) == s.charAt(right)){
right++;
left--;
}else{
break;
}
}
return new int[]{left +1, right-left-1};
}
}