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.

思路一:穷竭暴力搜索,事件复杂度为O(N^3)


思路二:判断一个字符串是否是回文,可以通过首位两个指针分别向中间靠近来判断。但在本题中,无法判断出首位的位置。所以可以通过从中间位置不断向外扩展来判断字串是否是回文以及回文的长度。该方法的时间复杂为O(N^2)。

class Solution {
public:

    string getP(string s,int l,int r)
    {
        int carry = 0;
        int count = 0;
        int left=l,right=r;

            
        while(left>0&&right<s.length())
        {
            left--;right++;
            if(s[left]==s[right])
                count++;
            else
                break;
        }
        
        if(count == 0)
            return s.substr(l,r-l+1);

        else
            return s.substr(l-count,r-l+2*count+1);
            
    }
    
    string longestPalindrome(string s) {
        int len = s.length();
        string result="";
        if(len == 0)
            return "";
        int i;
        for(i=0;i<len;i++)
        {
            string temp1 = getP(s,i,i);
            if(temp1.length() > result.length())
                result = temp1;
            
            if(i+1 < len && s[i] == s[i+1])
            {
                string temp2 = getP(s,i,i+1);
                if(temp2.length() > result.length())
                    result = temp2;
            }
        }
        return result;
    }
};


写完以后觉得代码好丑陋,对其进行优化。上面的代码调用了太多函数,消耗了很多时间。并且通过分析发现,当最中间的存在一系列相同的字符时,无论从其中哪一个字符开始,其形成的回文字串的长度都是相同的,这样可以进行一些剪枝。优化后的代码如下:

class Solution {
public:
    string longestPalindrome(string s) {
        int len = s.length();
        string result="";
        if(len == 0)
            return "";
        if(len == 1)
            return s;
        int i,l,r,start=0,max=0;
        for(i=0;i<len;i++)
        {
            l=i-1;
            r=i+1;
            while(l>=0&&s[l]==s[i])
                l--;
            while(r<=len&&s[r]==s[i])
                r++;
            i=r-1;
            while(l>=0&&r<=len&&s[l]==s[r])
            {
                l--;r++;
            }
            if(r-l-1>max)
            {
                start = l+1;
                max=r-l-1;
            }
                
        }
        return s.substr(start,max);
    }
};


思路三:可以采用动态规划。动态规划是十分重要的方法,动态规划适用于解法存在一种递推关系的问题。以本题为例,当table[i][j]=true代表索引i到j的字串为回文,那么table[i-1][j+1]=true则需要s[i-1]==s[j+1].

定义 P[ i, j ] ← 如果子串Si … Sj 是一个回文,那么该项为true, 否则为false.

P[ i, j ] 为 true ← ( P[ i+1, j-1 ]为true,并且Si = Sj )

基本条件:

P[ i, i ] 一定是true

P[ i, i+1 ] 为true ← ( Si = Si+1 )
class Solution {
public:
    string longestPalindrome(string s) {
        int i;
        int start = 0,max=1;
        int len = s.length();
        bool table[1000][1000] = {false};
        
        for(i=0;i<len;i++)
            table[i][i] = true;
        
        for(i=0;i<len-1;i++)
        {
            if(s[i] == s[i+1])
            {
                table[i][i+1] = true;
                start = i;
                max = 2;
            }
        }
        
        for(i=3;i<=len;i++)
            for(int j=0;j<len-i+1;j++)
            {
                if(s[j] == s[j+i-1] && table[j+1][j+i-2] == true)
                {
                    table[j][j+i-1] = true;
                    if(max < i)
                    {    
                        start = j;
                        max = i;
                    }
                }
            }
        return s.substr(start,max);
    }
};


感觉实现的性能不太行啊。。。


思路四:在网上搜索发现著名的Manacher算法,事件复杂度为 O(N)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值