-
1143最长公共子序列
- 代码随想录 (programmercarl.com)
-
第一印象
- 本题和718最长重复子数组的区别就是子集是否是连续的。
- 本题用暴力解法很难搜索出来。考虑直接使用动态规划的方法推导。回忆之前解决300最长上升的搜索不连续子集的方法。我们需要两层循环。
-
讲解观后感
- 确定dp数组(dp table)以及下标的含义
dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]
- 确定递推公式
- 主要就是两大情况: 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]);
- dp数组初始化
test1[0, i-1]和空串的最长公共子序列自然是0,所以dp[i][0] = 0;同理dp[0][j]也是0
-
解题代码
-
func longestCommonSubsequence(text1 string, text2 string) int {
t1 := len(text1)
t2 := len(text2)
dp:=make([][]int,t1+1)
for i:=range dp{
dp[i]=make([]int,t2+1)
}
for i := 1; i <= t1; i++ {
for j := 1; j <=t2; j++ {
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[t1][t2]
}
func max(a,b int)int {
if a>b{
return a
}
return b
}
-
1035不相交的线
- 代码随想录 (programmercarl.com)
-
讲解观后感
- 本题表面看似是一道图形题。但是我们可以发现,要想实现连接的线不相交,那么我们只要找到相同顺序的最大子序列就可以了。于是本题的解法就和上题完全一样了。
-
解题代码
-
func maxUncrossedLines(A []int, B []int) int {
m, n := len(A), len(B)
dp := make([][]int, m+1)
for i := range dp {
dp[i] = make([]int, n+1)
}
for i := 1; i <= len(A); i++ {
for j := 1; j <= len(B); j++ {
if (A[i - 1] == B[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]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
-
53最大子序和
- 代码随想录 (programmercarl.com)
-
第一印象
- 这题之前在用过一次贪心的方法,53最大子序和|01笔记 - 掘金 (juejin.cn)
- 这次尝试用动态规划的方式推导一遍。
-
讲解观后感
- 运用动态规划的方法,首先确定dp数组的含义。
dp[i]表示最大的连续子数组和,包含num[i] 元素。
- 易得dp[i]的结果只能由
dp[i-1]+和nums[i]得到。所以状态转移公式为dp[i] = max(dp[i-1]+nums[i],nums[i])
- 初始化时,dp[0]就等于nums[0]的值
- 由于我们得到的最大值不一定是最后位置的值,所以我们还需要维护一个最大值。
-
解题代码
-
func maxSubArray(nums []int) int {
n := len(nums)
dp := make([]int,n)
dp[0] = nums[0]
mx := nums[0]
for i:=1;i<n;i++ {
dp[i] = max(dp[i-1]+nums[i],nums[i])
mx = max(mx,dp[i])
}
return mx
}
func max(a,b int) int{
if a>b {
return a
}
return b
}