我是靠谱客的博主 闪闪巨人,最近开发中收集的这篇文章主要介绍【Leet Code】Longest Palindromic Substring ——传说中的Manacher算法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Longest Palindromic Substring

  Total Accepted: 17474  Total Submissions: 84472 My Submissions

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.


先解释一下题目的意思:

题目要求字符串的回文子字符串,所谓的回文字符串就是从左向右读和从右向左读都一样的字符串,例如:“abcba”或者“abba”

题目还假设字符串的最大长度为1000,而且有且只有一个最大的回文子字符串。

从上面的例子可知,回文字符串有奇偶之分,我们在字符串中插入特殊字符,把偶的情况也作为奇的情况处理:

例:abc -> @#a#b#c#$ (头尾插入不同的特殊字符是为了防止越界)

最简单的方法:

遍历字符串,使用一个数组prad[ ],prad[ i ]保存以第 i 个字符为中心的回文字符串的半径(这个新字符串的半径就刚好等于原字符串的长度)

然后再遍历这个数组就可以轻易得到子回文字符串了:

class Solution
{
public:
string change(string s)
{
string result = "!";
for (int i = 0; i < s.length(); i++)
{
result += "#";
result += s[i];
}
result += "#?";
return result;
}
string longestPalindrome(string s)
{
if (0 == s.length())
{
return "";
}
string new_s = this->change(s);
int size = new_s.length();
int* prad = new int[size];
for (int i = 1; i < size - 1; i++)
{
prad[i] = 0;
while (new_s[i - prad[i] - 1] == new_s[i + prad[i] + 1])
{
prad[i]++;
}
}
int maxLen{}, start_pos{};
for (int i = 1; i < size - 1; i++)
{
if (maxLen < prad[i])
{
maxLen = prad[i];
start_pos = (i - maxLen - 1) / 2;
}
}
delete[]prad;
return s.substr(start_pos, maxLen);
}
};


该算法的复杂度是O(n2),每一次都重新匹配太浪费时间了,我们可以利用前面匹配得到的信息,将下次匹配的范围缩小一点,这就是传说中的Manacher算法:

class Solution
{
public:
string change(string s)
{
string result = "!";
for (int i = 0; i < s.length(); i++)
{
result += "#";
result += s[i];
}
result += "#?";
return result;
}
string longestPalindrome(string s)
{
if (0 == s.length())
{
return "";
}
string new_s = this->change(s);
int size = new_s.length();
int* prad = new int[size];
int right_end{}, pos{};//记录匹配到的回文字符串达到的最右边,和该字符串的中心位置
for (int i = 1; i < size - 1; i++)
{
if (right_end > i)
{
prad[i] = min(right_end - i, prad[2 * pos - i]);
}
else
{
prad[i] = 0;
}
while (new_s[i - prad[i] - 1] == new_s[i + prad[i] + 1])
{
prad[i]++;
}
if (i + prad[i] > right_end)
{
right_end = i + prad[i];
pos = i;
}
}
int maxLen{}, start_pos{};
for (int i = 1; i < size - 1; i++)
{
if (maxLen < prad[i])
{
maxLen = prad[i];
start_pos = (i - maxLen - 1) / 2;
}
}
delete[]prad;
return s.substr(start_pos, maxLen);
}
};






最后

以上就是闪闪巨人为你收集整理的【Leet Code】Longest Palindromic Substring ——传说中的Manacher算法的全部内容,希望文章能够帮你解决【Leet Code】Longest Palindromic Substring ——传说中的Manacher算法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部