【leetcode】Longest Palindromic Substring

来源:互联网 发布:魔方一键网络共享工具 编辑:程序博客网 时间:2024/05/21 14:41

题目:

给定个字符串,返回串中包含的最长的回文串。

分析:

所谓回文串就是将字符串翻转后与原字串串相同,如 ABA,翻转后仍为ABA。
我们考虑用dp来做,因为我们很容易就想到dp的状态转移方程。
状态方程:m[i, j]: 表示子串s[i]...s[j] 是否为回文,若是,令其为true,否则为false。
状态转移:m[i, j] = m[i + 1, j - 1] if s[ i ] == s[ j ]。也就是说s[ i ... j ] 中,当首尾相同时,s[i  ... j ] 是否为为回文,要取决于m[ i + 1, j - 1] 是否为回文。
初始条件:m[i, i ] = true,这个好理解,一个字符的串就是回文串。但是,单单初始化对角线上的元素还不够(通过状态转移方程可以看出,不行的话自己画个m表,进行手写填表就很明了了),还要有m[i, i + 1] ,也就是主对角线右上的一层对角线信息。
结果:m表单纯的记录了是否为回文,这里要求的是返回最长的回文串,所以仅有m矩阵是不够的,还要我们定义额外的变量来记录结果。对于字符串而言,我们知道起始点,知道终止点 或者是起始点和长度,可以获得任意合法的子串,所以我们定义一个起始点变量start,长度变量longest。现在的问题是,start 和longest 要怎么样发生变化?什么时候发生变化呢?当然是当前的回文串长度大于已有回文串的长度的时候,当前回文串,也就是m[i, j ] 为true的时候,这就是当前获得的回文串,那么我们比较它的长度与longest的大小,若比longest大,则更新longest和start 的值。

最终填写的表是一个方阵的上对角矩阵。

表中黑色的部分是初始化的信息,然后从start开始,从下向上,从左向右填写表。每次填一行,如图中红色紫色所示。
到这,问题就很明了了。

实现:

//参考代码
string longestPalindrome(string s) {if(s.size() <= 1)return s;//vector<vector<bool> >dp(s.size(),vector<bool>(s.size(), false));bool dp[1000][1000] = {false};//bool **dp = new bool[s.size()][s.size()];int Len = s.size();int longest = 0;int start = 0;//init dp[i,i] = truefor (int i = 0; i < Len; ++i)dp[i][i]  = true;//init dp[i, i + 1] for (int i = 0; i < Len - 1; ++i) if(s[i] == s[i + 1])  {dp[i][i + 1] = true; longest = 2;start = i;}for (int i = Len - 3; i >= 0; --i)for(int j = i + 2; j < Len; ++j){if(dp[i + 1][j - 1] && s[i] == s[j]){dp[i][j] = true;if(longest < j - i + 1){longest = j - i + 1;start = i;}}}return s.substr(start,longest);}

说明:开始的实现中用vector来表示动态表,结果一直超时,看来封装过的容器效率上就是不比原生的数组。
0 0
原创粉丝点击