leetcode 5 -动态规划实例

https://leetcode-cn.com/problems/longest-palindromic-substring/

1. 题目

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

示例 1:

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

示例 2:

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

2.想法

思考:看到题目什么也想不出来。还是看答案!

3.解法

3.1暴力破解

时间复杂度为 O ( N 3 ) O(N^{3}) O(N3),空间复杂度为 O ( 1 ) O(1) O(1)

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        size = len(s)
        if size < 2:
            return s
        max_len = 1
        res = s[0]
        for i in range(size - 1):
            for j in range(i + 1, size):
                if j - i + 1 > max_len and self._value(s, i, j):
                    max_len = j - i + 1
                    res = s[i:j + 1]
        return res
    #验证子串是否为回文串
    def _value(self, s, i, j):
        while i < j:
            if s[i] != s[j]:
                return False
            else:
                i += 1
                j -= 1
        return True

3.2动态规划

在这里插入图片描述
我也想到了dp[i,j]=dp[i+1,j-1] and s[i]==s[j] 来进行状态转移。但是没有想到怎么初始化和输出(再定义一个变量保存数据,而不是输出dp)。
要多思考填表,自底而上!!!!!
根据状态转移公式得知,数据的方向是↙的,这样的推论要想正确,箭头数据必须是先得到的。那么如果顺序排列,那么箭头的就是最先进入求的数据。所以求数据的顺序就是

13
24

2↙3 , 我们先求2然后得到3,正确。

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        #定义dp[i][j] 为子串s[i][j]是否为回文子串
        size=len(s)
        dp=[[False for _ in range(size)] for _ in range(size)]
        for i in range(size):
            dp[i][i]=True
        max_len=1
        start=0
        for j in range(1,size):
            for i in range(j):
                if s[i]==s[j]:
                    if j-i<3:
                        dp[i][j]=True
                    else:
                        dp[i][j]=dp[i+1][j-1]
                else:
                    dp[i][j]=False

                if dp[i][j]:
                    cur_len=j-i+1
                    if cur_len>max_len:
                        max_len=cur_len
                        start=i

        return s[start:start+max_len]
24
13

1↙4,我们先求1,然后得到4,正确。

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        #定义dp[i][j] 为子串s[i][j]是否为回文子串
        size=len(s)
        dp=[[False for _ in range(size)] for _ in range(size)]
        for i in range(size):
            dp[i][i]=True
        max_len=1
        start=0
        for j in range(1,size):
            for i in range(j-1,-1,-1):
                if s[i]==s[j]:
                    if j-i<3:
                        dp[i][j]=True
                    else:
                        dp[i][j]=dp[i+1][j-1]
                else:
                    dp[i][j]=False

                if dp[i][j]:
                    cur_len=j-i+1
                    if cur_len>max_len:
                        max_len=cur_len
                        start=i

        return s[start:start+max_len]
43
21

2↙3,我们先求2,然后得到3,正确。

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        #定义dp[i][j] 为子串s[i][j]是否为回文子串
        size=len(s)
        dp=[[False for _ in range(size)] for _ in range(size)]
        for i in range(size):
            dp[i][i]=True
        max_len=1
        start=0
        for i in range(size-2,-1,-1):
            for j in range(size-1,i,-1):
                if s[i]==s[j]:
                    if j-i<3:
                        dp[i][j]=True
                    else:
                        dp[i][j]=dp[i+1][j-1]
                else:
                    dp[i][j]=False

                if dp[i][j]:
                    cur_len=j-i+1
                    if cur_len>max_len:
                        max_len=cur_len
                        start=i

        return s[start:start+max_len]
34
12

1↙4,我们先求1,然后得到4,正确。

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        #定义dp[i][j] 为子串s[i][j]是否为回文子串
        size=len(s)
        dp=[[False for _ in range(size)] for _ in range(size)]
        for i in range(size):
            dp[i][i]=True
        max_len=1
        start=0
        for i in range(size-2,-1,-1):
            for j in range(i+1,size):
                if s[i]==s[j]:
                    if j-i<3:
                        dp[i][j]=True
                    else:
                        dp[i][j]=dp[i+1][j-1]
                else:
                    dp[i][j]=False

                if dp[i][j]:
                    cur_len=j-i+1
                    if cur_len>max_len:
                        max_len=cur_len
                        start=i

        return s[start:start+max_len]

https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/

在这里插入图片描述

3.3中心扩散法

我也想到了中心法,但是没想清楚怎么区分回文串是奇数还是偶数的情况,所以放弃了。现在是把两种情况都计算一次,合计最大的子串就是结果。

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        #定义dp[i][j] 为子串s[i][j]是否为回文子串
        size=len(s)
        max_len=1
        res=s[0]
        for i in range(size):
            palindrome_odd, odd_len = self.__center_spread(s, size, i, i)
            palindrome_even, even_len = self.__center_spread(s, size, i, i + 1)

            #合并两种情况
            cur_max_sub = palindrome_odd if odd_len >= even_len else palindrome_even
            if len(cur_max_sub)>max_len:
                max_len=len(cur_max_sub)
                res=cur_max_sub


        return res

    def __center_spread(self, s, size, left, right):
        i=left
        j=right
        while i>=0 and j<size and s[i]==s[j]:
            i-=1
            j+=1
        return s[i+1:j],j-i-1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值