问题描述:
英文:
中文:
分析:
首先明确一个概念,字符串从前往后读和从后往前读是一样的。
那可以运用中心扩散的思想,找到一串字符的中间字符,分别向 left and right 扩散,直至到末尾。
两边相等是一个回文字符。
解决方案:
中心扩展算法
思路与算法
我们仔细观察一下方法一中的状态转移方程:
找出其中的状态转移链:
可以发现,所有的状态在转移的时候的可能性都是唯一的。也就是说,我们可以从每一种边界情况开始「扩展」,也可以得出所有的状态对应的答案。
边界情况即为子串长度为 11 或 22 的情况。我们枚举每一种边界情况,并从对应的子串开始不断地向两边扩展。如果两边的字母相同,我们就可以继续扩展。
附代码:
LANGUAGE: JavaScript
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function (s) {
if (s.length < 2) {
return s;
}
let start = 0;
let maxLength = 1;
function expandAroundCenter(left, right) {
while (left >= 0 && right < s.length && s[left] === s[right]) {
if (right - left + 1 > maxLength) {
maxLength = right - left + 1;
start = left;
}
left--;
right++;
}
}
for (let i = 0; i < s.length; i++) {
expandAroundCenter(i - 1, i + 1);
expandAroundCenter(i, i + 1);
}
return s.substring(start, start + maxLength);
};
LANGUAGE: Java
class Solution {
private int start = 0, maxLength = 1;
public String longestPalindrome(String s) {
if (s.length() < 2) {
return s;
}
for (int i = 0; i < s.length(); i++) {
expandAroundCenter(s, i - 1, i + 1);
expandAroundCenter(s, i, i + 1);
}
return s.substring(start, start + maxLength);
}
private void expandAroundCenter(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
if (right - left + 1 > maxLength) {
maxLength = right - left + 1;
start = left;
}
left--;
right++;
}
}
}
性能分析:
执行用时: 88 ms
内存消耗: 42.3 MB