代码随想录算法训练营day57 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和

1143.最长公共子序列

1、确定dp数组以及下标的含义

dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]

2、确定递推公式

主要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同

  • 如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;
  • 如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

3、数组的初始化

先看看dp[i][0]应该是多少呢?

test1[0, i-1]和空串的最长公共子序列自然是0,所以dp[i][0] = 0;

同理dp[0][j]也是0。

其他下标都是随着递推公式逐步覆盖,初始为多少都可以,那么就统一初始为0。

4、确定遍历顺序

要从前向后,从上到下来遍历这个矩阵。

5、举例推导dp数组

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)]
        for i in range(1, len(text1)+1):
            for j in range(1, len(text2)+1):
                if text1[i-1] == text2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1])
        return dp[-1][-1]

1035.不相交的线

本题和最长公共子序列是一样的

class Solution:
    def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int:
        dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)]
        for i in range(1, len(nums1)+1):
            for j in range(1, len(nums2)+1):
                if nums1[i-1] == nums2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    dp[i][j] = max(dp[i-1][j], dp[i] [j-1])
        return dp[-1][-1]

53. 最大子序和

贪心

遍历序列,累加中如果和小于0了,则重新开始累加

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        result = float('-inf')
        count = 0
        for num in nums:
            count += num
            result = max(result, count)
            if count <= 0:
                count = 0
        return result

动态规划

1、确定dp数组以及下标的含义:dp[i]表示以nums[i]结尾的最大和的连续子数组

2、确定递推公式:

dp[i]只有两个方向可以推出来:

  • dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和
  • nums[i],即:从头开始计算当前连续子序列和

一定是取最大的,所以dp[i] = max(dp[i - 1] + nums[i], nums[i]);

3、初始化dp数组:dp[0] = nums[0]

4、确定遍历顺序:从前向后遍历

5、举例推导dp数组

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        dp = [0] * len(nums)
        dp[0] = nums[0]
        result = nums[0]
        for i in range(1, len(nums)):
            dp[i] = max(dp[i-1]+nums[i], nums[i])
            result = max(result, dp[i])
        return result

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-06-17 00:30:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-17 00:30:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-17 00:30:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-17 00:30:03       18 阅读

热门阅读

  1. wifiphisher详细安装教程

    2024-06-17 00:30:03       8 阅读
  2. linux安装Vsftpd

    2024-06-17 00:30:03       8 阅读
  3. 力扣爆刷第149天之TOP100五连刷(LRU、K个一组)

    2024-06-17 00:30:03       6 阅读
  4. python嵌套指南

    2024-06-17 00:30:03       8 阅读
  5. CAPL如何在底层模拟TCP Client端断开TCP连接

    2024-06-17 00:30:03       6 阅读