题目:
https://leetcode.cn/problems/longest-palindromic-substring/
目的
求回文子串
由于我们事先无法确定最长回文子串的长度奇偶性,所以每次扩展都要取两次中心点,再取两者的扩展结果中长度较大的那个。代码如下,比较容易理解。
中心拓展法就是从中间向外拓展,用两个指针l和r,分别向前和向后遍历,如果两个指针的值不同,则停止遍历,如果相同,则代表一个回文字符串的诞生,继续遍历,直到边界。
注意:这里有一个需要注意的地方,就是字符串长度可以是奇数也可以是偶数
当回文串长度为奇数时,对称中心是具体的字符,如 “abababa”
但是当回文串长度为偶数时,对称中心会位于两个字符的间隙,如 abaaba -> aba|aba
以下标3来看,第一个字符串abababa的值为b
第一个字符串第一个应比较的应该为[a,a],跳过其本身,因为字符串长度为奇数,其本身无需比较。
以下标2来看,第二个字符串abaaba的值为a。
第二个字符串第一个应比较的应该为[a,a],其本身并不能跳过,因为字符串长度为偶数,其本身需要比较。若字符串为ababba,则不是回文串了。
代码
class Solution {
public String longestPalindrome(String s){
if(s == null || s.length() == 0){
return "";
}
// 数组第一位记录起始位置,第二位记录结束位置,第三位记录长度(单侧)
int[] res = new int[3];
for(int i = 0;i < s.length();i++){
int[] odd = expand(s,i,i);
int[] even = expand(s,i,i+1);
int[] max = odd[2] > even[2] ? odd : even;
if(max[2]>res[2]){
res = max;
}
}
return s.substring(res[0],res[1]+1);
}
private int[] expand(String s,int l,int r){
while( l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)){
l--;
r++;
}
l++;
r--;
return new int[]{l,r,r-l};
}
}