动态规划常见题(Python)

由于动态规划一直是一个比较难的点,因此在这里将leetcode刷题过程中碰到的比较常见的动态规划题记录下来。不定期更新。

1.最长回文子串

 

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

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

先上代码:

class Solution(object):
    def longestPalindrome(self, s):
        tempstr=res=[]
        for i in range(len(s)):
            #odd
            tempstr=self.longestPalindromeHelp(s,i,i)
            if len(tempstr)>len(res):
                res=tempstr
            #even
            tempstr=self.longestPalindromeHelp(s,i,i+1)
            if len(tempstr)>len(res):
                res=tempstr
        return res

    def longestPalindromeHelp(self,s,l,r):
        while l>=0 and r<len(s) and s[l]==s[r]:
            l-=1
            r+=1
        return s[l+1:r]

思路:从字符串的中间开始比较,若两字符相等,则同时向外移动一位,继续比较。需要注意的是,从中间开始需要分字符串为奇数和字符串为偶数两种情况。

2.最长公共字串和最长公共子序列

字串和子序列的区别在于字串要求字符必须是连续的,而子序列不要求连续。

最长公共字串的代码如下:

def find_substr(str1,str2):
    dp=[[0 for j in range(len(str2)+1)] for i in range(len(str1)+1)]
    maxlen=0
    for i in range(len(str1)):
        for j in range(len(str2)):
            if str1[i]==str2[j]:
                dp[i+1][j+1]=dp[i][j]+1
                if dp[i+1][j+1]>maxlen:
                    maxlen=dp[i+1][j+1]
                    index=i
    return maxlen,str1[index+1-maxlen:index+1]

最长公共子序列的递归公式如下:

代码如下:

def find_subseq(str1,str2):
    dp=[[0 for j in range(len(str2)+1)] for i in range(len(str1)+1)]
    ans=''
    for i in range(len(str1)):
        for j in range(len(str2)):
            if str1[i]==str2[j]:
                dp[i+1][j+1]=dp[i][j]+1
                ans+=str1[i]
            else:
                dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1])
    return dp[-1][-1],ans

需要指出的是该代码只能用于两字符串仅有一个最长公共子序列的情况。如果碰到如‘ABCBDAB’,‘BDCABA’会失效。

3.最长递增子序列(LIS)

复杂度为O(n^2)的方法:

class Solution(object):
    def lengthOfLIS(self, nums):
        if not nums:
            return 0
        dp=[1]*len(nums)
        for i in range(len(nums)):
            for j in range(i):
                if nums[i]>nums[j]:
                    dp[i]=max(dp[i],dp[j]+1)
        return max(dp)

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值