动态规划-------- dp数组套路学习

求两个数组或者字符串的子序列问题, 要用动态规划的时候:

当单个数组或者字符串要用动态规划时,可以把动态规划 dp[i] 定义为 nums[0:i] 中想要求的结果;当两个数组或者字符串要用动态规划时,可以把动态规划定义成两维的 dp[i][j] ,其含义是在 A[0:i−1] 与 B[0:j−1] 之间匹配得到的想要的结果。 https://leetcode.cn/problems/is-subsequence/solutions/1361126/by-nehzil-ixw6/

看别人的动态规划解法的时候,对 dp[i][j] 代表了什么一无所知就看不懂代码。要是把 dp[i][j] 理解为 s 字符串出现在 t[i:j] 中,即 t 中以 i 下标开始,j 下标结束的子字符串包含了 s,那要是不包含呢?岂不是解不出来。所以 dp[i][j] 就代表 s[0:i] 和 t[0:j] 的公共字符串长度,如果最后它等于 s.length ,那么s 字符串就被 t 字符串所包含。

所以 dp[i][j] 就是 s[0:i] 和 t[0:j] 在做比较,如果它们的最末尾字符 s[i-1]==t[j-1] ,那么dp[i][j]=dp[i-1][j-1] +1;dp[i-1][j-1] 代表 s[0:i-1] 和 t[0:j-1] 在做比较。

如果 s[i-1] !=t[j-1],那么就 j 前进一位,让 s[0:i] 和 t[j+1] 做比较,其实此时的比较结果和 s[0:i] 和 t[0:j-1] 的比较结果一样,即 dp[i][j]=dp[i][j-1] 。

这就是状态转移公式,在推导状态转移公式时,就像我们使用数学归纳法一样,因为它有最优子结构,dp[i][j] 要怎么得到?它的上一步是什么?这就是转态转移公式。然后考虑边界情况和初始情况,但最开始我们必须明确 dp[i][j] 的含义是什么。

Go 复制代码
func isSubsequence(s string, t string) bool {
	m, n := len(s), len(t)
	dp := make([][]int, m+1)
	for i := 0; i < m+1; i++ {
		dp[i] = make([]int, n+1)
	}
	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if s[i-1] == t[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else {
				dp[i][j] = dp[i][j-1]
			}
		}
	}
	return dp[m][n] == m
}
相关推荐
NGC_66112 分钟前
八大排序对比及实现
数据结构·算法·排序算法
进击的小头3 分钟前
第7篇:动态规划的数值求解算法
python·算法·动态规划
小红卒9 分钟前
Go语言安全开发学习笔记5:tls反弹shell升级到C2指令执行马
笔记·学习·网络安全·golang
峥嵘life12 分钟前
Android16 EDLA更新25-12补丁导致【CTS】CtsWindowManagerDeviceAnimations存在fail项
android·linux·学习
FMRbpm14 分钟前
斑马日记2026.3.13
数据结构·算法
NGC_66111 小时前
ArrayList扩容机制
java·前端·算法
做cv的小昊3 小时前
大语言模型系统:【CMU 11-868】课程学习笔记02——GPU编程基础1(GPU Programming Basics 1)
人工智能·笔记·学习·语言模型·llm·transformer·agent
xsyaaaan5 小时前
leetcode-hot100-双指针:283移动零-11盛最多水的容器-15三数之和-42接雨水
算法·leetcode
炽烈小老头8 小时前
【每天学习一点算法 2026/03/08】相交链表
学习·算法·链表
一碗白开水一9 小时前
【工具相关】OpenClaw 配置使用飞书:打造智能飞书助手全流程指南(亲测有效,放心享用)
人工智能·深度学习·算法·飞书