5. Longest Palindromic Substring

来源:互联网 发布:网络搜索不到打印机 编辑:程序博客网 时间:2024/06/16 21:49

问题

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example:

Input: “babad”

Output: “bab”

Note: “aba” is also a valid answer.
Example:

Input: “cbbd”

Output: “bb”

计算最长回文子序列

解析

参考博客1
动态规划求解最长子串的长度
状态初始条件:

dp[i][i]=1i=0n1)

状态转移方程:
dp[i][j]=dp[i+1][j1]+2(str[i]==str[j])

dp[i][j]=max(dp[i+1][j],dp[i][j1])ifstr[i]!=str[j]

最终返回dp[0][n1]
计算dp[i][j]时需要计算dp[i+1][]或dp[][j-1],因此i应该从大到小,即递减;j应该从小到大,即递增。

代码:

以下代码为根据该思路写的【一本正经】,且是求最长回文子序列广为流传的代码。看我main中的测试样例pwwkew,最终结果为3,因为dp[3][4] = 1,计算dp[2][5]时,就是dp[3][4]+2 = 3,而非正确结果2。找的多个博客代码运行起来都一样,怎么肥四?有猫病??先放着吧,可能哪儿细节我没看清?

#include<iostream>#include<algorithm>#include<string>#include<vector>#include<unordered_map>using namespace std;// 按照转移方程自己打的class Solution {public:    int longestPalindrome(string s) {        // matrix[i][j]是s下标从i到j的子串中最长回文子序列的长度        int size = s.size();        vector<vector<int>> dp(size, vector<int>(size, 0));        for (int j = 0; j < size; j++) {            dp[j][j] = 1;            for (int i = j - 1; i >= 0; i--) {                if (s[i] == s[j]) {                    dp[i][j] = dp[i + 1][j - 1] + 2;                }                else {                    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);                }            }        }        return dp[0][size - 1];    }};// 另外一种博客上做法,总体思路还是一致int lpsDp(string str, int n){    int dp[6][6], tmp;    memset(dp, 0, sizeof(dp));    //字符串长度为1,最长回文子序列的长度就是1      for (int i = 0; i < n; ++i)  dp[i][i] = 1;    for (int i = 1; i < n; ++i)    {        tmp = 0;        //考虑所有连续的长度为i+1的子串,str[j....j+i]          for (int j = 0; j + i < n; j++)        {            //如果首尾相同              if (str[j] == str[j + i])                tmp = dp[j + 1][j + i - 1] + 2;            //如果首尾不同              else                tmp = max(dp[j + 1][j + i], dp[j][j + i - 1]);            dp[j][j + i] = tmp;        }    }    return dp[0][n - 1]; //返回字符串str[0...n-1]的最长回文子序列长度  }int main() {    string str = "pwwkew";    Solution solution;    //int res = solution.longestPalindrome(str);    int res = lpsDp(str, str.size());    cout << res << endl;    system("pause");    return 0;}

就题论题

解析:

来自原题的solution
相应AC代码:

#include<iostream>#include<algorithm>#include<string>#include<vector>#include<unordered_map>using namespace std;class Solution {public:    string longestPalindrome(string s) {        // matrix[i][j]是s下标从i到j的子串是否是回文串        int size = s.size();        vector<vector<bool>> dp(size, vector<bool>(size, false));        for (int i = 0; i < size; i++) {            dp[i][i] = true;  // 奇数情况初始化            if (i < size - 1) {                dp[i][i + 1] = (s[i] == s[i + 1]);  // 偶数情况初始化            }        }        // 转移方程        for (int window = 3; window <= size; window++) {            for (int index = 0; index + window - 1 < size; index++) {                dp[index][index + window - 1] = (s[index] == s[index + window - 1]) && dp[index + 1][index + window - 2];            }        }        // 找出dp[index][index + window - 1]为true,window最大的子序列        int index, window;        for (window = size; window > 0; window--) {            bool flag = false;            for (index = 0; index < size - window + 1; index++) {                if (dp[index][index + window - 1]) {                    flag = true;                    break;                }            }            if (flag)                break;        }        string substring;        substring.assign(s, index, window);        return substring;    }};int main() {    string str = "abcba";    Solution solution;    string res = solution.longestPalindrome(str);    cout << res << endl;    system("pause");    return 0;}
原创粉丝点击