[leetcode]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.

链接:https://oj.leetcode.com/problems/longest-palindromic-substring/

描述:求最大长度的回文子串

解法:常见的解法有DP和中间向外扩展两种方式,时间复杂度O(n^2),而该复杂度算法使用python会出现TLE,采用时间复杂度为O(n)的Manacher算法可过python。

Manacher算法根据已发现的最长回文子串确定新子串的最大长度,算法介绍见:http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html


solution implemented by Manacher's algorithm in python:

class Solution:
    # @return a string
    def longestPalindrome(self, s):
        s_pro = self.preProcess(s)
        p = [0 for i in range(len(s_pro))]
        c=0;r=0
        for i in range(1, len(s_pro)-1):
            _i = 2*c - i
            p[i] = min(p[_i], r-i) if r>i else 0
            while s_pro[i-p[i]-1] == s_pro[i+p[i]+1]: p[i] += 1
            if p[i]+i > r:
                c = i
                r = p[i]+i
        maxlen = 0; ct=0;
        for i in range(len(s_pro)):
            if p[i] > maxlen: maxlen=p[i];ct=i;
        return s[(ct-1-maxlen)/2: (ct+maxlen)/2]
    def preProcess(self, s):
        n = len(s)
        if n==0: return "^$"
        res = "^"
        for i in range(n):
            res += '#'+s[i]
        res += "#$"
        return res
solution by dp in c++:

设f(i,j)表示字符串s[i...j]是否为回文字符串,那么状态转义方程如下:

if i==j or (i==j-1 and s[i]==s[j])  then f(i,j)=true

else if s[i]==s[j] and f(i+1, j-1)==true then f(i,j)=true

else f(i,j)=false

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.size() < 2) return s;
        int low=0, high=0;
        int len = s.size();
        vector<vector<bool> > dp(len, vector<bool>(len));
        for(int i=len-1; i>=0; i--){
            for(int j=i; j<len; j++){
                if(i==j || s[i]==s[j] &&(i==j-1 || dp[i+1][j-1])){
                    dp[i][j] = true;
                    if(high-low < j-i){
                        high = j;
                        low = i;
                    }
                }
            }
        }
        return s.substr(low, high-low+1);
    }
};
其他解法:以所有字母为中心,尽力向两端扩展找以该字母为中心可以形成的最大回文,在所有回文中找出最大的子串。复杂度O(n^2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值