leetcode5:最长回文子串

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuweiyuxiang/article/details/83142939

1 题目

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

示例 1:

输入: “babad”
输出: “bab”
注意: "aba"也是一个有效答案。

示例 2:

输入: “cbbd”
输出: “bb”

题目链接:
https://leetcode-cn.com/problems/longest-palindromic-substring/description/

2 解法

2.1 中心扩展法

class Solution {
public:
    string longestPalindrome(string s) {
    if(s == NULL || s.size() <= 1)
    	return s;
        int start = 0;
        int end = 0;
        for(int i = 0; i < s.size(); i++){
            int len1 = maxlen(s,i,i);
            int len2 = maxlen(s,i,i+1);
            int len = len1 > len2 ? len1 : len2;
            //cout<<"len:"<<len<<endl;
            if(len > end - start){ # 新的子串余当前子串长度相等就更新,如果有几个相同长度的子串,找出的是最后一个;如果写成if(len > end - start),则新的子串大于当前子串长度才更新,如果有几个相同长度的子串,找出的是最前一个
                //cout<<"start:"<<start<<" end:"<<end<<endl;
                start = i - (len - 1)/2;
                end = i + len / 2;
            }
        }
        return s.substr(start,end-start+1);
    }
    int maxlen(string s,int i,int j){
        int left= i;
        int right=j;
        while(left >= 0 && right < s.size() && s[left] == s[right]){
            left--;
            right++;
        }
        return right - left - 1;
    }
};

2.2 动态规划法

class Solution {
public:
	string longestPalindrome(string s) {
        if(s.size() == 0)
            return s;
		const int n=s.size();
		bool dp[n][n];
		fill_n(&dp[0][0],n*n,false);
		int max_len=1; //保存最长回文子串长度
		int start=0;//保存最长回文子串起点
		for(int i=0;i<s.size();++i)
		{
			for(int j=0;j<=i;++j)
			{
				if(i-j<2)
					dp[j][i]=(s[i]==s[j]);
				else
					dp[j][i]=(s[i]==s[j] && dp[j+1][i-1]);
				if(dp[j][i] && max_len<(i-j+1))
				{
					max_len=i-j+1;
					start=j;
				}
			}
		}
		return s.substr(start,max_len);
	}
};

解析:回文串就是正着读和反着读一样的字符串,如“abba”,“abcba”,最长回文子串是字符串的子串中最长的属于回文串的子串。如字符串"abbaabccba"的最长回文子串为"abccba",本文采用动态规划算法来查找最长回文子串,算法时间复杂度为O(n²)。**设状态dp[j][i]表示索引j到索引i的子串是否是回文串。**则易得转移方程如下:
在这里插入图片描述
则dp[j][i]为true时表示索引j到索引i形成的子串为回文子串,且子串起点索引为i,长度为j+i-1。

2.3 暴力求解法

暴力求解就是列举出s的左右子串,判断是否是回文子串,如果是判断其长度是否大于找到的上一个回文子串,大于则更新否则不更新。

参考博客:动态规划算法求最长回文子串

猜你喜欢

转载自blog.csdn.net/liuweiyuxiang/article/details/83142939