LeetCode 3.5 Longest Palindromic Substring
2016-04-18 15:38
465 查看
3.5 Longest Palindromic Substring
描述
Given a stringS, find the longest
palindromic substring inS. You may assume that the maximumlength ofS
is 1000, and there exists one unique longest palindromic substring.
3.5 Longest Palindromic Substring61
分析
最长回文子串,非常经典的题。思路一:暴力枚举,以每个元素为中间元素,同时从左右出发,复杂度O(n2)。思路二:记忆化搜索,复杂度O(n2)。设f[i][j]表示[i,j]之间的最长回文子串,递推方程如
下:
思路三:动规,复杂度O(n2)。设状态为f(i,j),表示区间[i,j]是否为回文串,则状态转移方
程为
true , i=
j
f(i,
j) =S[i]
= S[j],
j =i
+ 1S[i]=S[j]andf(i+1,j−1),j>i+1
思路三:Manacher’s
Algorithm, 复杂度O(n)。详细解释见http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html。
备忘录法
// LeetCode, Longest Palindromic Substring//备忘录法,会超时
//时间复杂度O(n^2),空间复杂度O(n^2)typedef string::const_iterator Iterator; namespace std {
template<>
struct hash<pair<Iterator, Iterator>> {
} class Solution {
public:
auto key = make_pair(first, last);
auto pos = cache.find(key);
动规
// LeetCode, Longest Palindromic Substring//动规,时间复杂度O(n^2),空间复杂度O(n^2)class Solution {
public:
string longestPalindrome(string s) {
const int n = s.size();
bool f
;
fill_n(&f[0][0], n * n, false);
// 用vector会超时
//vector<vector<bool> > f(n, vector<bool>(n, false));size_t max_len = 1, start = 0; //最长回文子串的长度,起点 for (size_t i = 0; i < s.size(); i++) {
f[i][i] = true;
for(size_tj=0;j<i;j++){ //[j,i]
f[j][i] = (s[j] == s[i] && (i - j < 2 || f[j + 1][i - 1]));if (f[j][i] && max_len < (i - j + 1)) { max_len = i - j + 1;
start = j;}
}} return s.substr(start, max_len);
}
};
Manaer’s Algorithm
// LeetCode, Longest Palindromic Substring// Manacher’s Algorithm
// 时间复杂度O(n),空间复杂度O(n)
class Solution { public:
// Transform S into T.
// For example, S = "abba", T = "^#a#b#b#a#$".
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
string preProcess(string s) {
return ret;
}
string longestPalindrome(string s) {
string T = preProcess(s);
const int n = T.length();
// 以T[i]为中心,向左/右扩张的长度,不包含T[i]自己,//因此P[i]是源字符串中回文串的长度 int P
;
int C = 0, R = 0;
// adjust center based on expanded palindrome.
if (i + P[i] > R) {
C = i;
R = i + P[i];}
} // Find the maximum element in P.
int max_len = 0;
int center_index = 0;
for (int i = 1; i < n - 1; i++) {
}
};
描述
Given a stringS, find the longest
palindromic substring inS. You may assume that the maximumlength ofS
is 1000, and there exists one unique longest palindromic substring.
3.5 Longest Palindromic Substring61
分析
最长回文子串,非常经典的题。思路一:暴力枚举,以每个元素为中间元素,同时从左右出发,复杂度O(n2)。思路二:记忆化搜索,复杂度O(n2)。设f[i][j]表示[i,j]之间的最长回文子串,递推方程如
下:
f[i][j] = if (i == j) S[i] if (S[i] == S[j] &am e3f0 p;& f[i+1][j-1] == S[i+1][j-1]) S[i][j] else max(f[i+1][j-1], f[i][j-1], f[i+1][j])
思路三:动规,复杂度O(n2)。设状态为f(i,j),表示区间[i,j]是否为回文串,则状态转移方
程为
true , i=
j
f(i,
j) =S[i]
= S[j],
j =i
+ 1S[i]=S[j]andf(i+1,j−1),j>i+1
思路三:Manacher’s
Algorithm, 复杂度O(n)。详细解释见http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html。
备忘录法
// LeetCode, Longest Palindromic Substring//备忘录法,会超时
//时间复杂度O(n^2),空间复杂度O(n^2)typedef string::const_iterator Iterator; namespace std {
template<>
struct hash<pair<Iterator, Iterator>> {
size_t operator()(pair<Iterator, Iterator> const& p) const { return ((size_t) &(*p.first)) ^ ((size_t) &(*p.second));}};
} class Solution {
public:
string longestPalindrome(string const& s) { cache.clear();
return cachedLongestPalindrome(s.begin(), s.end()); }
private: unordered_map<pair<Iterator, Iterator>, string> cache;
string longestPalindrome(Iterator first, Iterator last) { size_t length = distance(first, last);
if (length < 2) return string(first, last);
auto s = cachedLongestPalindrome(next(first), prev(last));
if (s.length() == length - 2 && *first == *prev(last)) return string(first, last);
auto s1 = cachedLongestPalindrome(next(first), last); auto s2 = cachedLongestPalindrome(first, prev(last));
// return max(s, s1, s2) if (s.size() > s1.size()) return s.size() > s2.size() ? s : s2; else return s1.size() > s2.size() ? s1 : s2;} string cachedLongestPalindrome(Iterator first, Iterator last) {
auto key = make_pair(first, last);
auto pos = cache.find(key);
if (pos != cache.end()) return pos->second;
else return cache[key] = longestPalindrome(first, last); }};
动规
// LeetCode, Longest Palindromic Substring//动规,时间复杂度O(n^2),空间复杂度O(n^2)class Solution {
public:
string longestPalindrome(string s) {
const int n = s.size();
bool f
;
fill_n(&f[0][0], n * n, false);
// 用vector会超时
//vector<vector<bool> > f(n, vector<bool>(n, false));size_t max_len = 1, start = 0; //最长回文子串的长度,起点 for (size_t i = 0; i < s.size(); i++) {
f[i][i] = true;
for(size_tj=0;j<i;j++){ //[j,i]
f[j][i] = (s[j] == s[i] && (i - j < 2 || f[j + 1][i - 1]));if (f[j][i] && max_len < (i - j + 1)) { max_len = i - j + 1;
start = j;}
}} return s.substr(start, max_len);
}
};
Manaer’s Algorithm
// LeetCode, Longest Palindromic Substring// Manacher’s Algorithm
// 时间复杂度O(n),空间复杂度O(n)
class Solution { public:
// Transform S into T.
// For example, S = "abba", T = "^#a#b#b#a#$".
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
string preProcess(string s) {
int n = s.length(); if (n == 0) return "^$";
string ret = "^"; for (int i = 0; i < n; i++) ret += "#" + s.substr(i, 1);ret += "#$";
return ret;
}
string longestPalindrome(string s) {
string T = preProcess(s);
const int n = T.length();
// 以T[i]为中心,向左/右扩张的长度,不包含T[i]自己,//因此P[i]是源字符串中回文串的长度 int P
;
int C = 0, R = 0;
for (int i = 1; i < n - 1; i++) { int i_mirror = 2 * C - i; // equals to i' = C - (i-C)
P[i] = (R > i) ? min(R - i, P[i_mirror]) : 0;
// Attempt to expand palindrome centered at i while (T[i + 1 + P[i]] == T[i - 1 - P[i]])P[i]++; // If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + P[i] > R) {
C = i;
R = i + P[i];}
} // Find the maximum element in P.
int max_len = 0;
int center_index = 0;
for (int i = 1; i < n - 1; i++) {
if (P[i] > max_len) { max_len = P[i];
center_index = i;}} return s.substr((center_index - 1 - max_len) / 2, max_len);
}
};
相关文章推荐
- 正确使用Volatile关键字
- 地理信息检索
- dom4j读写xml
- 【ASP.NET】ASP.NET中gridview中点击某一行刷新后不会到顶部
- (13)处理静态资源(默认资源映射)【从零开始学Spring Boot】
- c++实现mysql数据库数据缓存
- xml绘制总结——shape,selector,layer-list
- caffe读书笔记1 CIFAR-10在caffe上进行训练与学习
- 【Chromium中文文档】OS X 沙箱设计
- 贪吃蛇C语言代码
- Eclipse保存时自动格式化代码
- win基础
- Java Debug 调试
- Swift 图片下拉放大
- 20160418Ubuntu升级出现boot空间不足解决
- Android ViewDragHelper:控制子View垂直方向拖曳不能越界(3)
- diy数据库(五)--文件操作、问题诊断和配置文件
- position=absolute之相对父元素定位
- ARP笔记
- iOS 给UILabel添加下划线