当前位置:实例文章 » 其他实例» [文章]Day53| 1143.最长公共子序列、1035.不相交的线 、 53. 最大子序和 动态规划

Day53| 1143.最长公共子序列、1035.不相交的线 、 53. 最大子序和 动态规划

发布人:shili8 发布时间:2024-12-29 00:03 阅读次数:0

**Day53 |1143. 最长公共子序列、1035. 不相交的线、53. 最大子序和**

在本篇博客中,我们将讨论三个动态规划问题:最长公共子序列(Longest Common Subsequence)、不相交的线(Non-Intersecting Lines)和最大子序和(Maximum Subarray Sum)。这些问题都涉及到如何找到一个序列或一组元素之间的最优解。

###1. 最长公共子序列**1143. 最长公共子序列**

给定两个字符串 `s1` 和 `s2`,我们需要找到它们的最长公共子序列(LCS)。这意味着我们需要找出两个字符串中共同出现的最大子串。

#### 动态规划解决方案我们可以使用动态规划来解决这个问题。我们创建一个2D 数组 `dp`,其中 `dp[i][j]` 表示 `s1` 的前 `i` 个字符和 `s2` 的前 `j` 个字符的最长公共子序列。

def longestCommonSubsequence(s1, s2):
 m, n = len(s1), len(s2)
 dp = [[0] * (n +1) for _ in range(m +1)]

 for i in range(1, m +1):
 for j in range(1, n +1):
 if s1[i -1] == s2[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[m][n]


####代码注释* 我们首先创建一个 `dp` 数组,大小为 `(m +1) x (n +1)`,其中 `m` 和 `n` 是 `s1` 和 `s2` 的长度。
* 然后,我们遍历 `s1` 和 `s2` 的所有字符,并更新 `dp` 数组。我们检查当前字符是否相同,如果相同,则更新 `dp[i][j]` 为 `dp[i -1][j -1] +1`,否则取 `dp[i -1][j]` 和 `dp[i][j -1]` 的最大值。
* 最后,我们返回 `dp[m][n]` 作为最长公共子序列的长度。

###2. 不相交的线**1035. 不相交的线**

给定一个点集 `points`,我们需要找到不相交的线段数。两个线段不相交当且仅当它们没有公共点。

#### 动态规划解决方案我们可以使用动态规划来解决这个问题。我们创建一个2D 数组 `dp`,其中 `dp[i][j]` 表示第 `i` 个线段和第 `j` 个线段是否不相交。

def maxUncrossedLines(points):
 n = len(points)
 dp = [[0] * n for _ in range(n)]

 for i in range(n):
 for j in range(i, n):
 if points[i][0] == points[j][0]:
 dp[i][j] =1 elif points[i][0] < points[j][0]:
 dp[i][j] = dp[i +1][j]
 else:
 dp[i][j] = dp[i][j -1]

 return sum(dp[i][i] for i in range(n))


####代码注释* 我们首先创建一个 `dp` 数组,大小为 `n x n`,其中 `n` 是点集的长度。
* 然后,我们遍历点集,并更新 `dp` 数组。我们检查当前线段是否不相交,如果不相交,则更新 `dp[i][j]` 为1,否则取 `dp[i +1][j]` 和 `dp[i][j -1]` 的值。
* 最后,我们返回 `dp` 中所有对角元素的和作为不相交线段数。

###3. 最大子序和**53. 最大子序和**

给定一个整数数组 `nums`,我们需要找到最大子序列和。这个问题等价于找出最长递增子序列(LIS)的长度。

#### 动态规划解决方案我们可以使用动态规划来解决这个问题。我们创建一个1D 数组 `dp`,其中 `dp[i]` 表示以 `nums[i]` 为结尾的最大子序和。

def maxSubArray(nums):
 n = len(nums)
 dp = [0] * (n +1)

 for i in range(1, n +1):
 if nums[i -1] > dp[i -1]:
 dp[i] = nums[i -1]
 else:
 dp[i] = dp[i -1]

 return max(dp[1:])


####代码注释* 我们首先创建一个 `dp` 数组,大小为 `(n +1)`,其中 `n` 是数组的长度。
* 然后,我们遍历数组,并更新 `dp` 数组。我们检查当前元素是否大于前一个最大子序和,如果大于,则更新 `dp[i]` 为当前元素值,否则取前一个最大子序和。
* 最后,我们返回 `dp` 中所有非零元素的最大值作为最大子序和。

以上就是本篇博客中讨论的三个动态规划问题:最长公共子序列、不相交的线和最大子序和。这些问题都涉及到如何找到一个序列或一组元素之间的最优解。

其他信息

其他资源

Top