leetCode-5 最长回文子串

题目描述

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

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:

输入: "cbbd"
输出: "bb"

复制代码

思路1 中心扩散

首先确认一下什么是回文串,aba属于回文串,aa也属于回文串。也就是说回文串分为两种状况,长度为奇数是是以最中间的单个字符开始往两边扩散。长度为偶数时须要以最中间的两个字符开始扩散。所以须要考虑两种扩散方式。web

代码以下:数组

// 从l向左扩散和从r向右扩散,返回此时的最长回文串
string palindrome(string s, int l, int r) {
    while(l >= 0 && r < s.size() && s[l] == s[r]) {
        l--;
        r++;
    }
    return s.substr(l+1, r-l-1);
}

string longestPalindrome(string s) {
    if(s.size() == 0) {
        return "";
    }
    string ans = s.substr(0, 1);
    for(int i = 0; i < s.size()-1; i++) {
    	// 求出从i为中心开始向左右两侧扩散的最长回文串
        string same = palindrome(s, i, i);
        // 求出从i和i+1为中心开始向左右两侧扩散的最长回文串
        string notSame = palindrome(s, i, i+1);
        ans = ans.size() < same.size() ? same : ans;
        ans = ans.size() < notSame.size() ? notSame : ans;
    }
    return ans;
}
复制代码

时间复杂度为o(n*n),空间复杂度为o(1)markdown

思路2 动态规划

数组dp[i][j]表示字符串s[i,j]区间的子串是否为回文串。 咱们能够肯定的是:url

1. if(i == j) dp[i][j] = true
2. if(i < j) dp[i][j] = false
复制代码

如何根据dp[i][j]来求解其余的值呢?spa

若是s[i]!=s[j],很显然dp[i][j]=false3d

s[i]==s[j]的状况下,若是dp[i+1][j-1]=true,此时dp[i][j]=true,此时咱们能够得出状态转移方程:code

dp[i][j] = dp[i+1][j-1] && s[i]==s[j]
复制代码

根据上图来看,此时咱们已经能够肯定dp[i][j]的值了,由于先决条件已经都有了。可是咱们还须要考虑到一点,在dp[i][i+1]的状况时,即j-i+1=2时,咱们只须要判断s[i]和s[j]是否相等,例如求解dp[0][1]的时候,dp[1][0]=false,已经失去了参考价值。 代码以下:orm

string longestPalindrome(string s) {
    size_t length = s.size();
    int dp[length][length];
    int maxLen = 1;
    int start = 0;
    for(int i = 0; i < length; i++) {
        dp[i][i] = true;
    }
    for(int j = 1; j < length; j++) {
        for(int i = 0; i < j; i++) {
            if(s[i] != s[j]) {
                dp[i][j] = false;
            }else {
                if(j - i < 2) {
                    dp[i][j] = true;
                }else {
                    dp[i][j] = dp[i+1][j-1];
                }
                if(dp[i][j] && j-i+1 > maxLen) {
                    start = i;
                    maxLen = j-i+1;
                }
            }
        }
    }
    
    return s.substr(start, maxLen);
}
复制代码

时间复杂度为o(n* n),空间复杂度为o(n*n)ci

相关文章
相关标签/搜索