《重启15》
最长回文子串-中心扩散法
前言
周六某数字公司的笔试要来了,这也是博主第二次参加大厂笔试了,其他连简历都过不了,第一参加美团的自闭半小时就退了,现在虽然有点实力,但大概率也会被刷下去。。。兄弟们,加油吧!!
回文字符串与中心扩散法
- 回文字符串
回文字符串顾名思义就是以字符串的中心两边相互对称,比如经典语句:上海自来水来自海上。以水为中心两边对称。
比如:abababa中有很多个回文字符串,例如:aba,ababa,abababa,bab,babab
- 中心扩散法
中心扩散法顾名思义就是以中心向两边扩散,同时对比等价位置上的字符是否相同,进而判断该字符串是否为回文字符串。
题目
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
来源:力扣(LeetCode)
解题思路
博主最近菜鸟总结了一点做题技巧,一旦字符串题目涉及最长最短的,并且还让你找到它在哪,除非有很巧妙的技巧,不然就会涉及一个是对比函数Math.max/Math.min,一个是字符串的起始位置,所以这道题这两个点是没逃的,然后又是关于回文串的,那中心扩散法是没逃的,然后中心扩散法要考虑你它是否是奇数字符串还是偶数字符串,现在,整个答题思路就下来了,但是怎么组织编码实现这又是一大难点,但是这也是编程算法的魅力,需要兄弟们,多学多练,废话不多说直接上代码!!
具体代码
private static int n;
public int getLen(String s, int i, int j){
//以初始的i、j为回文中心向两边扩后对比
while(i >= 0 && j < n && s.charAt(i) == s.charAt(j)){
i --;
j ++;
}
return j - i - 1; //减1是因为i、j跳出循环时多执行了--和++操作
// 所以上面的判断语句一定要把 s.charAt(i) == s.charAt(j)放到最后,不然如果情况是s.charAt(-1)会报错
}
public String longestPalindrome(String s) {
n = s.length();
int maxLen = 0;
int l = 0, r = 0; //子串的左右边界
for(int i = 0;i < n;i ++){
//假设其为奇数字符串进行回文字符串判断,并返回其为回文字符的长度
int len1 = getLen(s, i, i);
//假设其为偶数字符串进行回文字符串判断,并返回其为回文字符的长度
int len2 = getLen(s, i, i + 1);
//Math.max(len1,len2)其实是省去一段if/else判断是否为奇数长度还是偶数的字符串,
//如果他是偶数字符串中有回文串的len1必返回0,同理也是。
if(Math.max(len1, len2) > maxLen){
maxLen = Math.max(len1, len2);
l = i - (maxLen - 1) / 2;
r = i + maxLen / 2;
}
}
return s.substring(l, r + 1);
}