https://leetcode-cn.com/problems/longest-palindromic-substring/
题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
输入: “cbbd”
输出: “bb”
思路1
暴力,枚举回文中心点,向两边延伸直到不回文,统计最长的字串即可
代码
class Solution {
public:
string longestPalindrome(string s) {
int n = s.length();
string ans;
int l, r;
for (int i = 0; i < n; i++) {
l = i, r = i;
while (s[l] == s[r]) {
l--; r++;
if (l < 0 || r == n) break;
} l++; r--;
if (r - l + 1 > ans.length()) ans = s.substr(l, r - l + 1);
l = i - 1, r = i;
if (l < 0) continue;
while (s[l] == s[r]) {
l--; r++;
if (l < 0 || r == n) break;
} l++; r--;
if (r - l + 1 > ans.length()) ans = s.substr(l, r - l + 1);
}
return ans;
}
};
思路2
学习了一下manacher算法,又叫马拉车算法
1. 首先解决奇数回文和偶数回文不一致的问题,给原字符串每个字符之间加个分隔符,这里用 ‘#’ ,并且头尾再加上两个不同的字符用来截止,以免数组越界。例如,字符串 “abc” ,处理后变成 “!#a#b#c#$” ,这样所有回文字串都是奇数长度,统一起来
2. 然后我们维护两个值,center,和 maxR,maxR表示字符串中各回文串能够延伸到的最远的位置,而 center是该子串的中心,这样我们可以分成两种情况
(1) 当前位置 i >= maxR,不知道dp[i],置为1,等待后续延伸
(2) 当前位置 i < maxR,我们找到 i 关于 center的对称点,也就是 center * 2 - i,因为是回文的,所以对称点在以 center为中心的子串以内的回文子串是和 i 点一样的,这时令 dp[i] = min(dp[center * 2 - i], maxR),不能超过了,因为对称点还可能包含center回文串以外的字串,所以只能取这之间的较小值
3. dp[i] 暂时的值确定了,接下来进行延伸,两端的字符一样 dp[i] 就++,直到不一样为止,这时候那两个不同的字符作用就出来了,不设两个不同的,比到后来会越界。
4. 最后更新 maxR
5. 遍历一遍长度数组,找到最长的下标,提取正确字符串
代码
class Solution {
public:
string longestPalindrome(string s) {
string ans;
if (!s.length()) return ans;
string ns = "*#";
for (int i = 0; i < s.length(); ++i) {
ns += s[i]; ns += '#';
} ns += '-';
vector <int> dp(ns.length());
int maxR(0), center(0);
for (int i = 1; i < ns.size() - 1; i++) {
if (maxR > i)
dp[i] = min(dp[center * 2 - i], maxR - i);
else dp[i] = 1;
while (ns[i + dp[i]] == ns[i - dp[i]])
dp[i]++;
if (dp[i] + i > maxR) {
maxR = i + dp[i];
center = i;
}
}
int a(0), b(0);
for (int i = 0; i < dp.size(); i++) {
if (dp[i] > b) a = i, b = dp[i];
}
for (int i = a - dp[a] + 1; i < a + dp[a]; i++)
if (ns[i] != '#') ans += ns[i];
return ans;
}
};

本文详细解析了LeetCode上经典题目——寻找最长回文子串的两种算法实现:暴力解法和Manacher算法(马拉车算法)。通过实例演示如何找到字符串中的最长回文子串,包括奇数和偶数长度的回文情况。
773

被折叠的 条评论
为什么被折叠?



