[LeetCode]516. Longest Palindromic Subsequence

516. Longest Palindromic Subsequence

题意:求字符串中回文串的最大长度。

动态规划

分析:假设dp[i][j]为字符串从i到j的回文串的最大长度,如果字符i等于j,则将之前的长度加上2;如果不相等,那么要么忽略i,要么忽略j,取两者的最大值,所以状态转移方程为:

dp[i][j] = 2 + dp[i+1][j-1] (if s[i]==s[j])
dp[i][j] = max(dp[i+1][j], dp[i][j-1]) (else)

因为我们最终的结果求的是dp[0][l-1],所以要保证最终的结果是前面的结果得出来的,所以第一个循环要从后往前扫!

class Solution(object):
    def longestPalindromeSubseq(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        l = len(s)
        dp = [[0 for i in range(l)] for j in range(l)]
        for i in range(l-1, -1, -1):
            dp[i][i] = 1
            for j in range(i+1, l):
                if s[i] == s[j]:
                    dp[i][j] = 2 + dp[i+1][j-1]
                else:
                    dp[i][j] = max(dp[i+1][j], dp[i][j-1])
        return dp[0][l-1]

但是上面的做法还是TLE了,还有一种滚动数组的做法,可以减少一定的空间复杂度,需要注意的是因为是j在变化,所以j要在最外层,如果在内层的话,不断的遍历就会替换掉之前的值,但是还是超时了:

class Solution(object):
    def longestPalindromeSubseq(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        l = len(s)
        dp = [[1] * 2 for i in range(l)]
        for j in range(1, l):
            for i in range(j-1, -1, -1):
                if s[i] == s[j]:
                    dp[i][j%2] = 2 + dp[i+1][(j-1)%2] if i + 1 <= j - 1 else 2
                else:
                    dp[i][j%2] = max(dp[i+1][j%2], dp[i][(j-1)%2])
        return dp[0][(l-1)%2]

我们还可以替换数组来达到我们的目的,AC,看来要把空间复杂度优化到一维才行。

class Solution(object):
    def longestPalindromeSubseq(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        l = len(s)
        dp = [0 for i in range(l)]
        for i in range(l-1, -1, -1):
            newdp = dp[:]
            newdp[i] = 1
            for j in range(i+1, l):
                if s[i] == s[j]:
                    newdp[j] = 2 + dp[j-1]
                else:
                    newdp[j] = max(dp[j], newdp[j-1])
            dp = newdp[:]
        return dp[l-1]
posted @ 2017-08-31 19:30  banananana  阅读(179)  评论(0编辑  收藏  举报