[LeetCode]33. 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, and there exists one unique longest palindromic substring.

解法一:考虑回文字符串paliStr的特征,分为字符串长度为奇偶两种情况:(1)paliStr.size()为奇数时,则从最中间的一个字符往两边扩展是对称的,例如abcdcba;(2)paliStr.size()为奇数时,则从最中间的两个字符往两边扩展是对称的,例如abccba。因此可以得到如下思路:(1)初始化最长回文子串长度maxLen=0,当前最长回文子串长度curMax=1,最长回文子串lstPali="";(2)(奇数情况处理)从i=1到i=str.size()-2遍历一遍输入字符串,以当前字符为中心,往左右对称扩展,若对称位置字符一致,则curMax+=2,然后继续往左右扩展,直到抵达字符串的首尾端;否则若maxLen<curMax,则设置maxLen=curMax,且更新lstPali;(3)(偶数情况处理)设置当前最长回文子串长度curMax=2,从i=0到i=str.size()-2遍历一遍输入字符串,如果第i个字符和第i+1个字符相同,则以它们为中心往左右对称扩展,若对称位置字符一致,则curMax+=2,然后继续往左右扩展,直到抵达字符串的首尾端;否则若maxLen<curMax,则设置maxLen=curMax,且更新lstPali。时间复杂度为O(n*n)。

class Solution {
public:
    string longestPalindrome(string s) {
        int ss = s.size();
        if(ss < 2)
            return s;
        if(ss == 2)
            (s[0] == s[1]) ? return s : return string(s.begin(), s.begin() + 1);
           
        int maxLen = 0;
        string res;        
        int left, right;
        for(int i = 1; i < ss; i++)
        {
            left = right = i;
            int curMax = 1;
            curMax += findLstPali(s, left, right);
            if(curMax > maxLen)
            {
                maxLen = curMax;
                string tmp(s.begin() + left, s.begin() + right + 1);
                res = tmp;
            }
        }
        
        for(int i = 0; i < ss - 1; i++)
        {
            if(s[i] == s[i + 1])
            {
                left = i;
                right = i + 1;
                int curMax = 2;
                curMax += findLstPali(s, left, right);
                if(curMax > maxLen)
                {
                    maxLen = curMax;
                    string tmp(s.begin() + left, s.begin() + right + 1);
                    res = tmp;
                }
            }
        }        
        return res;
    }
    
private:
    int findLstPali(string& str, int& left, int& right)
    {
        int ss = str.size();
        int len = 0;
        while (true)
        {
            --left;
            ++right;
            if (left >= 0 && right < ss)
            {
                if (str[left] == str[right])
                    len += 2;
                else
                    break;
            }
            else
                break;
        }

        ++left;
        --right;
        return len;
    }
};

解法二:使用动态规划方法。

原文地址:https://www.cnblogs.com/aprilcheny/p/4851502.html