Leetcode解题笔记 5.Longest Palindromic Substring [Medium] 动态规划解法

版权声明:自由转载-非商用-非衍生-保持署名 https://blog.csdn.net/mgsweet/article/details/78713355

注:实现中参照了http://blog.csdn.net/ebowtang/article/details/50698672的代码

解题思路

题目要求我们寻找长度最长的子字符串,考虑到由于题目符合运用动态规划的3个性质——最优化原理、无后效性、有重叠子问题,所以可以用动态规划的方法。难点在于构造如何设定子问题,怎么初始化,以及怎么遍历。

构建子问题:
设d[i][j]表示字符串s从第i个字符到第j个字符为回文(字符串从0开始),则
若d[i+1][j-1] == true,并且s[i] == s[j],则d[i][j] == true;

初始化
由于算法运行只能判断3个字符以上回文的情况,我们要预先对d[i][i], d[i][i+1]进行赋值。

遍历
为了避免考虑字符串边界的问题,需要谨慎设计循环,参考上面给出的链接,里面没有直接拿i,j去进行循环,而是巧妙地把j设为i - len + 1,从而避免了出界。

代码

#define MAX_N 1000

string longestPalindrome(string s) {
    bool f[MAX_N][MAX_N] = {false};

    //  情况一
    int begin = 0;
    int maxLen = 1;
    for (int i = 0; i < s.length(); i++) {
        f[i][i] = true;
    }

    //  情况二
    for (int i = 0; i < s.length() - 1; i++) {
        if (s[i] == s[i + 1]) {
            begin = i;
            maxLen = 2;
            f[i][i + 1] = true;
        } 
    }

    //  情况三
    for (int len = 3; len <= s.length(); len++) {
        for (int i = 0; i < s.length() - len + 1; i++) {
            int j = i + len - 1;
            if (s[i] == s[j] && f[i + 1][j - 1]) {
                maxLen = len;
                begin = i;
                f[i][j] = true;
            }
        }
    }
    return s.substr(begin, maxLen);
}

猜你喜欢

转载自blog.csdn.net/mgsweet/article/details/78713355