5. Longest Palindromic Substring

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 1:

Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.
Example 2:

Input: “cbbd”
Output: “bb”
即要求对于给定的一个字符串输出其最长的回文子串。

解法一:

O(n3):暴力求解,对于字符串的每个子串进行回文分析,一个n个字符的字符串有n2的子串,每个子串平均长度为n/2,所以算法时间复杂度为O(n3)。
O(n2):利用动态规划的思想,用字符 i 表示字符串中的第i个字符,用f(i,j)表示从字符 i 到字符 j 的子串是否是回文子串;
那么f(i,j) = true的情况有两种:1.i = j,即这个子串只有一个字符;2.s[i] = s[j] 并且f(i+1,j-1) = true,即子串首尾两个字符相同并且中间的子串也是回文的。
那么题目所求得最长回文子串就是在f(i,j) = true的情况下j-i最大的时候对应的子串。
通过构建一个二维数组,并且进行双循环的求解,就可以得出最终的结果,所以算法的时间复杂度和空间复杂度都是O(n2)。

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        if(n <= 1)
            return s;
        bool dp[n][n];
        int maxLen = 0;
        int maxI = 0;
        for(int j = 0;j < n;j++)
        {
            for(int i = 0;i <= j ;i++)
            {
                dp[i][j] = (s[i] == s[j] && ((j-i <= 1) || dp[i+1][j-1]));
                if(dp[i][j] && j-i > maxLen)
                {
                    maxLen = j - i;
                    maxI = i;
                }
            }
        }
        return s.substr(maxI,maxLen+1);
    }
};

解法二:

O(n):Manacher 算法

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        if(n <= 1)
            return s;
        char olds[n];
        strncpy(olds,s.c_str(),n);
        int newn = 2*n+1;
        char news[newn];
        int j = 0;
        for(int i = 0;i < n;i++)
        {
            news[j++] = '#';
            news[j++] = olds[i];
        }
        news[j] = '#';
        int RL[newn];
        int maxRight = 0;
        int pos = 0;
        int maxLen = 0;
        int maxI = 0;
        for(int i = 0;i < newn;i++)
        {
            if(i < maxRight)
            {
                RL[i] = maxRight - i;
                if((maxRight - i) > RL[2*pos-i])
                    RL[i] = RL[2*pos-i];
            }
            else
                RL[i] = 1;
            while(i - RL[i] >= 0 && i + RL[i] < newn && news[i-RL[i]] == news[i+RL[i]])
            {
                RL[i]++;
            }
            if(RL[i] + i - 1 > maxRight)
            {
                maxRight = RL[i] + i - 1;
                pos = i;
            }
            if(maxLen <= RL[i])
            {
                maxLen = RL[i];
                maxI = i;
            }
        }
        return s.substr((maxI-maxLen+1)/2,maxLen-1);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值