题目
- 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
中心扩展算法详解
- 这代码很好理解,主要是卡了我很久的地方为这个索引的计算,仔细推敲之下才搞清楚关于这些索引的细节点:在代码里我已经具体注释出来。
- 最关键的问题不仅限于本文,很多时候都是这样卡住思路一卡一整天,所以必须总结思考,关于这类的索引下标问题,必须要逐个推敲,才能写出自己思路的完整代码,最好举例子让自己理解,不懂的代码要先敲一下,再理解,再自己重新写,这样才能吃透,思路必须清晰,唉,晚安自己
代码实现
- 详细的索引推敲见代码注释
package com.immunize.leetcode.longestPalindrome;
/**
* 2.暴力法优化
*
* @author Mr IMMUNIZE
*
*/
public class Solution2 {
public String longestPalindrome(String s) {
if (s == null || s.length() < 1)
return "";
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
// 字符串的长度为奇数时,从同一字符出发进行中心扩展
String str1 = Excenter(s, i, i);
// 字符串的长度为奇数时,从该字符和其后相邻字符出发进行中心扩展
String str2 = Excenter(s, i, i + 1);
// 获取两种比较之下的最长回文字符串的长度
int len = Math.max(str1.length(), str2.length());
// 更新长度信息
if (len > end - start) {
// 当前起始索引要往前退 的值和当前结束索引往后退的值: 分开算,
// 奇数的话,(当前长度-1)/2 或 当前长度/2
// 偶数的话,(当前长度-1)/2
// 统一起始点索引为 当前索引 - (当前长度-1)/2
// 当前结束索引往后退的值: 分开算,
// 奇数: 当前长度/2 或 (当前长度-1)/2
// 偶数:当前长度/2
// 统一结束点索引:当前索引 + 当前长度/2
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
// 截取start-end闭区间的所有字符
return s.substring(start, end + 1);
}
private String Excenter(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return s.substring(left + 1, right);
}
}
- 效率明显提升了很多
3. 马拉车算法真的看不懂,我先睡了,明天再看,这题能卡我一周