5. Longest Palindromic Substring

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”

方法一:
Brute Force,时间 O ( n 3 ) ,超时,空间 O ( 1 )

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.empty() || s.size() == 1)
            return s;
        int len = s.size(), maxlen = 0, start=0;
        for(int i = 0; i < len; i++ )//子串的长度
        {
            for(int j =0; j< len - i; j++)//子串起始的位置
            {
                if(isPalindrome(s,i,j) && (i+1)>maxlen)
                {
                    maxlen = i+1;
                    start = j;
                }
            }
        }
        return s.substr(start,maxlen);
    }

private:
    bool isPalindrome(string s ,int len ,int start)
    {
        int left = start, right = start + len;
        while(left < right)
        {
            if(s[left] == s[right])
            {
                left ++;
                right --;
            }
            else
                return false;
        }
        return true;
    }
};

方法二:DP,时间 O ( n 2 ) ,空间 O ( n 2 )
参考:http://www.cnblogs.com/grandyang/p/4464476.html
此题还可以用动态规划Dynamic Programming来解,根Palindrome Partitioning II 拆分回文串之二的解法很类似,我们维护一个二维数组dp,其中dp[i][j]表示字符串区间[i, j]是否为回文串,当i = j时,只有一个字符,肯定是回文串,如果i = j + 1,说明是相邻字符,此时需要判断s[i]是否等于s[j],如果i和j不相邻,即i - j >= 2时,除了判断s[i]和s[j]相等之外,dp[j + 1][i - 1]若为真,就是回文串,通过以上分析,可以写出递推式如下:

dp[i, j] =  1                                  if i == j                                      
         = s[i] == s[j]                        if j = i + 1
         = s[i] == s[j] && dp[i + 1][j - 1]    if j > i + 1      

这里有个有趣的现象就是如果我把下面的代码中的二维数组由int改为vector

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.size() < 2)
            return s;
        int len = s.size(), maxlen = 0, start=0 ,end = 0;
        int dp[len][len] = {0};//区间[i,j]
        for(int i = 0; i < len; ++i )
        {
            for(int j =0; j <= i; ++j)//子串起始的位置
            {
                dp[j][i] = (s[i] == s[j] && (i - j < 2 || dp[j + 1][i - 1]));
                if(dp[j][i] && i - j + 1 > maxlen)
                {
                    maxlen = i - j + 1;
                    start = j;
                    end = i;
                }
            }
            //dp[i][i] = 1;
        }
        return s.substr(start, end-start+1);
    }
};

方法三:中心扩散法,时间 O ( n 2 ) ,空间 O ( 1 )

class Solution {
    string res="";//设置全局变量
public:
    string longestPalindrome(string s) {
        if(s.size() < 2)
            return s;
        for(int i = 0; i < s.size(); ++i)
        {
            helper(s,i,i);
            helper(s,i,i+1);//无中心点,偶数情况
        }
        return res;
    }

private:    
    void helper(string s ,int left, int right)
    {
        while(left >= 0 && right < s.size() && s[left] == s[right])
        {
            left --;
            right ++;//中心扩散
        }//跳出时,left+1到right-1为回文,
        string cur = s.substr(left+1, right-left-1);//len=right-1-(left+1)+1=right-left-1
        if(cur.size() > res.size())
            res = cur;
    }
};

猜你喜欢

转载自blog.csdn.net/chineseqsc/article/details/79972504