标签:
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.
思路:
两种做法
第一种做法:动态规划
1、设f[i][j]表示从下标i到j的字符串是不是回文串
2、f[i][j] = (f[i + 1][j - 1] && s[i] == s[j])
3、这个动态规划的阶段划分根本就是减少2的长度后,看能不能继续扩展
4、边界条件:
a.单个字符都是回文的
b.既然要砍掉2的长度才能判断以前的阶段,那么我们可以直接构建2的长度为边界条件(if (s[k] == s[k + 1]) 则是回文的)
5、驱动阶段划分的是字符串的长度
注意:很遗憾的是,上面的算法没有能够通过leetcode,错误原因是内存不够
分析一下,字符串最长如果是1000的话,那么存储空间就是1000 * 1000
为了能让动态规划也能够通过leetcode oj,我把上面的状态转移方程的f[i][j]的意义改为"以i下标开始,j长度的字符串是否为回文"
这样在动态开辟空间的时候,能够节约一半的空间,因为i越靠后,j的值也就越小
源代码如下:
#include <iostream> #include <string> #include <vector> using namespace std; class Solution { public: string longestPalindrome(string s) { int iLen = s.size(); if (iLen == 0) return s; bool ** pArr = NULL; pArr = (bool **)new bool *[iLen]; for (int i = 0; i < iLen; ++i) { pArr[i] = new bool[iLen - i + 1]; } int iMaxLen = 0; string strResult; for (int i = 1; i <= iLen; ++i) { for (int j = 0; j <= iLen - i; ++j) { if (i == 1) { pArr[j][1] = true; } else if (i == 2) { if (s[j] == s[j + 1]) { pArr[j][2] = true; } else { pArr[j][2] = false; } } else if (pArr[j + 1][i - 2] && s[j] == s[j + i - 1]) { pArr[j][i] = true; } else { pArr[j][i] = false; } if (pArr[j][i] && i > iMaxLen) { iMaxLen = i; strResult = s.substr(j, i); } } } for (int i = 0; i < iLen; ++i) { delete [] pArr[i]; } delete [] pArr; return strResult; } }; int main() { Solution a; string strResult = a.longestPalindrome("aa"); printf("%s\n", strResult.c_str()); system("pause"); return 0; }
第二种做法:
用Manacher算法,具体的Manacher算法可以去网上搜索,我是看的如下这篇文章
http://www.open-open.com/lib/view/open1419150233417.html
其主要思想是通过回文串的对称性,查看自己的子串是否也是回文串,当不满足条件或者越界的时候,就继续向后遍历
具体的算法,参见网上的各文章,自己演算一遍就很清楚了
我的代码有一些冗余,但在leetcode上也算跑出了4ms的好成绩,差强人意吧
源代码如下:
#include <iostream> #include <string> #include <vector> using namespace std; class Solution { public: string longestPalindrome(string s) { string strConvert; if (s.size() <= 1) return s; for (int i = 0; i < s.size(); ++i) { strConvert += ‘#‘; strConvert += s[i]; } strConvert += ‘#‘; int p0 = 0, p = 0, j; int * pLen = new int[strConvert.size()]; pLen[0] = 1; int iMaxLen = 1; int iMaxLabel = 0; int iCount = 0; for (int i = 1; i < strConvert.size(); ++i) { if (i <= p) { j = 2 * p0 - i; if (pLen[j] + i - 1 < p) { pLen[i] = pLen[j]; } else { iCount = p - i + 1; int k = p + 1; while (k < strConvert.size() && 2 * i - k >= 0 && strConvert[k] == strConvert[2 * i - k]) { ++iCount; ++k; } pLen[i] = iCount; p0 = i; p = i + iCount - 1; } } else { iCount = 1; int k = i + 1; while ( k < strConvert.size() && 2 * i - k >= 0 && strConvert[k] == strConvert[2 * i - k]) { ++iCount; ++k; } pLen[i] = iCount; p0 = i; p = i + iCount - 1; } if (pLen[i] > iMaxLen) { iMaxLen = pLen[i]; iMaxLabel = i; } } delete [] pLen; string strResult; if (iMaxLabel % 2) { strResult = s.substr(iMaxLabel / 2 - (iMaxLen - 1) / 2, iMaxLen - 1); } else { strResult = s.substr((iMaxLabel - 1) / 2 - (iMaxLen - 1) / 2 + 1, iMaxLen - 1); } return strResult; } }; int main() { Solution a; string strResult = a.longestPalindrome("abba"); printf("%s\n", strResult.c_str()); system("pause"); return 0; }
leetcode [005] : Longest Palindromic Substring
标签:
原文地址:http://www.cnblogs.com/lqy1990cb/p/4809628.html