LeetCode | 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"

解题思路:问题是要求最长的回文串,并返回这个子串.一种思路是动态规划,(就是我的思路),O(n^2) 89ms AC,有注释,很好想到;另一种就是大佬提供的思路,从头开始以每个字符为中心向两边扩散,并附带一些优化.最后达到O(n) 6ms AC.
其实我认为,就算不优化,针对以每个字符为中心位置扩散,只要考虑ABA和ABBA两种情况,然后对长度做一个小优化,性能应该也不错吧.事实证明,9ms AC.
下面附上三种代码,按照上面叙述的顺序.

class Solution {
public:
    string longestPalindrome(string s) {
        //dp[i][j] 表示 s[i,j] 是否是一个回文串。 dp[i][j] = (s[i]==s[j] && dp[i+1][j-1])
        int len = s.length(), MaxLen = 1, left = 0;
        bool dp[1100][1100]={};

        if(s.length() == 0)
            return "";
        else if(s.length() == 1)
            return s;

        for(int i=0;i<len;i++)
            dp[i][i] = true;
        for(int i=len-1;i>=0;i--)
        {
            for(int j=i+1;j<len;j++)
            {
                dp[i][j] = ((s[i]==s[j])&&(dp[i+1][j-1] || j==i+1));
                if(dp[i][j])
                {
                    if(j-i+1 > MaxLen)
                    {
                        MaxLen = j-i+1;
                        left = i;
                    }
                }
            }
        }
        return s.substr(left,MaxLen);
    }
};
class Solution {
public:
    string longestPalindrome(string s) {
        if (s.length() < 2)
            return s;
        int len = s.size(), max_left = 0, max_len = 1, left, right;
        for (int start = 0; start<len && len-start>max_len/2 && start+1>max_len/2;)
        {
            //从中心向两端扩散
            left = start;
            right = start;
            while (right < len - 1 && s[right + 1] == s[right])
                right++;
            start = right + 1;
            while (right<len-1 && left>0 && s[right + 1]==s[left - 1])
            {
                right++;
                left--;
            }
            if (max_len < right - left + 1)
            {
                max_left = left;
                max_len = right - left + 1;
            }
        }
        return s.substr(max_left, max_len);
    }
};
class Solution {
public:
    string longestPalindrome(string s) {
        if (s.length() < 2)
            return s;
        int len = s.size(), max_left = 0, max_len = 1, left, right;
        for (int start = 0; start<len && len-start>max_len/2 && start+1>max_len/2;start++)
        {
            //从中心向两端扩散
            left = start;
            right = start;
            while (right<len-1 && left>0 && s[right + 1]==s[left - 1])
            {
                right++;
                left--;
            }
            if (max_len < right - left + 1)
            {
                max_left = left;
                max_len = right - left + 1;
            }
            left = start;
            right = start+1;
            if(s[left] == s[right])
            {
                while (right<len-1 && left>0 && s[right + 1]==s[left - 1])
                {
                    right++;
                    left--;
                }
                if (max_len < right - left + 1)
                {
                    max_left = left;
                    max_len = right - left + 1;
                }
            }


        }
        return s.substr(max_left, max_len);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值