https://leetcode-cn.com/problems/longest-palindromic-substring/description/https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。:
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。
示例 2:
输入: "cbbd"
输出: "bb"
思路:
马拉车算法。这个Manache算法,在网上找了很多中文资料,个人觉得对某些边界条件和时间复杂度解释得都不够清楚。
目前找到个人认为最清晰的解释在这:https://www.cnblogs.com/Lyush/p/3221503.html
class Solution {
public:
string longestPalindrome(string s) {
// 为了更专注的理解Manache算法的核心,这里没有像Manache加上特殊字符#
// 采用最直观的实现(分别计算奇数和偶数回文子串)
const char* char_s = s.c_str();
int s_len = s.length();
int radius[1000] = {0};
radius[0] = 0;
int max_pos_1 = 0;
int right_bound_1 = 0;
// 寻找奇数回文子串
for (int i = 1; i < s_len; ++i) {
int mirror_i = 2 * max_pos_1 - i;
// i在右边界内
if (i < right_bound_1) {
int mirror_radius = mirror_i >= 0 ? radius[mirror_i] : 0;
radius[i] = min(right_bound_1 - i, mirror_radius);
// 这里特地加上这个条件,明确表明当二者相等的时候,还需要继续进行后续累加。
if (right_bound_1 - i != mirror_radius) {
continue;
}
}
// 继续累加回文子串长度,这里合并了2种情况:1. i在右边界外面;2. i到右边界的长度和镜像的半径相等
while (i + radius[i] < s_len && i - radius[i] > 0) {
if (char_s[i + (radius[i] + 1)] != char_s[i - (radius[i] + 1)]) {
break;
}
++radius[i];
}
// 更新当前最大右边界和相应的中心点
if (i + radius[i] > right_bound_1) {
max_pos_1 = i;
right_bound_1 = i + radius[i];
}
}
int radius_2[1000] = {0};
radius_2[0] = 0;
int max_pos_2 = 0;
int right_bound_2 = 0;
// 寻找偶数回文子串
for (int i = 1; i < s_len; ++i) {
int mirror_i = 2 * max_pos_2 - i;
if (i < right_bound_2) {
int mirror_radius = mirror_i >= 0 ? radius_2[mirror_i] : 0;
radius_2[i] = min(right_bound_2 - i, mirror_radius);
if (right_bound_2 - i != mirror_radius) {
continue;
}
}
while (i + radius_2[i] < s_len && i - radius_2[i] > 0) {
if (char_s[i + radius_2[i]] != char_s[i - (radius_2[i] + 1)]) {
break;
}
++radius_2[i];
}
if (i + radius_2[i] > right_bound_2) {
max_pos_2 = i;
right_bound_2 = i + radius_2[i];
}
}
// 遍历寻找最长半径
int max_pos = 0;
int max_radius = 0;
for (int i = 0; i < s_len; ++i) {
if (radius[i] > max_radius) {
max_pos = i;
max_radius = radius[i];
}
}
bool even_mirror = false;
for (int i = 0; i < s_len; ++i) {
if (radius_2[i] > max_radius) {
even_mirror = true;
max_pos = i;
max_radius = radius_2[i];
}
}
// 构造结果返回
int pos = 0;
int len = 1;
if (!even_mirror) {
pos = max_pos - max_radius;
len = 2 * max_radius + 1;
} else {
pos = max_pos - max_radius;
len = 2 * max_radius;
}
string res(char_s + pos, len);
return res;
}
};