String-5. Longest Palindromic Substring

来源:互联网 发布:单车淘宝 编辑:程序博客网 时间:2024/06/05 08:51

题目描述:
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. 本题是求一个字符串中的最长回文子串。所谓回文串就是正着读和倒着读是一样的。
2. 传统暴力求解:需要时间复杂度O(n^3)。其实就是:从第一个字符开始,固定子串start,依次以第2,3,4…为end,再判断start和end之间的字符串是不是回文串。再固定第二个字符为start,依次以第3,4,5…为end来判断。
3. 要做到降低时间复杂度,会发现字符串比如:ababad。在判断子串“ababa”是不是回文串时,如果bab已经判断过是回文,此时就没有必要挨个比对。str[start]==str[end]。则便是回文了。这就需要一个辅助数组来存储之前比对的结果,方便后续子串比对来利用,做到在时间上的降维。即:动态规划来解决。


解题方法:
// 使用动态规划:设置辅助数组dp[size][size],size为给定字符串str的的长度。dp[i][j]表示str中i位置到j位置代表的子串中回文串的字符个数。
// 状态转移方程:if(str[i] == str[j]),若j-i==1或者dp[i+1][j-1]>0;则dp[i][j] = 2+dp[i+1][j-1];
// 代码

class Solution {public:    // 使用动态规划算法,可以使得时间复杂度从O(n3)将到O(n2),但是会多出一个O(n2)的空间复杂度    string longestPalindrome(string s)     {        if(s.empty())            return NULL;        int size = (int)s.size();        vector<vector<int>> dp;        dp.resize(size);        for(int i=0; i<size; ++i)            dp[i].resize(size);        // 初始化最中间的斜竖行        for(int i=0; i<size; ++i)            dp[i][i] = 1;        //沿着对角线一次开始填充dp;        for(int j=1; j<size; ++j)        {            for(int i=0; i<size-j; ++i)            {                if(s[i] == s[i+j])                {                    if(j==1)                        dp[i][i+j] = 2;                    else                    {                        if(dp[i+1][i+j-1] == 0)                            dp[i][i+j] = 0;                        else                            dp[i][i+j] = 2+dp[i+1][i+j-1];                    }                }            }        }         // 填充完毕,找寻最大值就好        int start = -1, end = -1, max = 0;        for(int i=0; i<size; ++i)        {            for(int j=i; j>=i && j<size; ++j)            {                if(dp[i][j]>max)                {                    start = i; end=j; max=dp[i][j];                }            }        }          string strOut;        strOut.assign(s, start, max);         return strOut;    }};