力扣53题、1143题(最大子数组问题、最长公共子序列)

53、最大子数组问题

基本思想:

动态规划

具体实现:

1、确定状态

(1)最后一步-----以nums[i]结尾的“最大子数组和”

(2)子问题----以nums[i-1]结尾的“最大子数组和”

知道了nums列表中以每一个数字结尾的最大子数组和,找出其中最大的就可以了

2、转移方程

dp[i]=max(nums[i],nums[i]+dp[i-1])

与前面的相邻子树组连接,形成一个更大的子数组。

不予前面的子数组连接,自己作为一个子数组。

3、初始条件

dp数组初始都为0

dp[0]=nums[0]

4、计算顺序

从前往后

5、状态压缩

计算出dp数组后,还要找其中的最大值,需要两个循环

因为dp[i]只与dp[i-1]有关,所以只要设两个变量记录就可,不需要设出dp数组

代码:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 0:
            return 0
        dp_0 = nums[0]
        dp_1 = 0
        res = dp_0

        for i in range(1,n):
            dp_1 = max(nums[i], nums[i]+dp_0)
            dp_0 = dp_1
            res = max(res,dp_1)
        return res

 

1143、最长公共子序列

基本思想:

动态规划

具体实现:

1、确定状态:

(1)最后一步---dp[i][j]是对于s1[0:i-1]和s2[0:j-1],它们的最长公共子序列长度

(2)子问题---dp[i-1][j],dp[i][j-1],dp[i-1][j-1]

2、转移方程:

(1)如果s1[i] == s2[j],说明有一个公共字符

dp[i][j] = dp[i-1][j-1] +1

(2)如果s1[i] != s2[j],说明至少有一个字符不是公共字符

dp[i][j] = max(dp[i-1][j],dp[i][j-1])

3、初始状态:

让索引为0的行和列表示空串,dp[0][...] 和 dp[...][0] 都应该初始化为0

4、计算顺序:

从上往下,从左到右

代码:

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m = len(text1)
        n = len(text2)
          dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
        # 可以不加1,但是不加1就会用其它限制条件来确保这个index是有效的,加1之后就不需要去判断
        # 只是让索引为0的行和列表示空串
        for i in range(1,m+1):
            for j in range(1,n+1):
                if text1[i-1] == text2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    dp[i][j] = max(dp[i][j-1],dp[i-1][j])
        return dp[m][n]

 

 

 

 

posted @ 2021-03-13 11:12  最近饭吃的很多  阅读(95)  评论(0编辑  收藏  举报