题目描述
给了两个数组,可以把数组中相同的数组连起来,限制条件是连线不能相交
问最多能连多少根?
基本分析
- 为啥不能贪心?例如134和341,如果1一定要往后取,只能1,最好的结果是2
- 怎么变形?找到两个字符串的LCS,可以满足索引的限制要求
- 为啥在求LCS的时候会存在重复情况?状态定义为f[i][j]表示前i序列和前j序列的LCS值,这里可以不一定要求包含第i和第j个字符。对于而包含情况会有
s1[i] |
s2[j] |
表示 |
不含 |
不含 |
f[i-1][j-1] |
包含 |
包含 |
f[i-1][j-1] + 1 |
不含 |
包含 |
无法表示 1+3 = f[i-1][j] |
包含 |
不含 |
无法表示 1+3 = f[i][j-1] |
因为是求max,保证不漏就行,不需要不重,所以2、3、4可以包含所有情况
代码
| class Solution: |
| def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int: |
| m, n = len(nums1), len(nums2) |
| f = [[0] * (n + 1) for _ in range(m + 1)] |
| |
| for i in range(1, m+1): |
| for j in range(1, n+1): |
| f[i][j] = max(f[i-1][j], f[i][j-1]) |
| if nums1[i-1] == nums2[j-1]: |
| f[i][j] = max(f[i][j], f[i-1][j-1] + 1) |
| |
| return f[m][n] |
| |
总结
- 能看出来不是贪心
- 能看出来是LCS的变形题
- 能深刻理解状态定义的含义,理解为啥进行了重复计算,但是又可以重复计算
- 在定义状态的时候因为有-1的情况,多定义了一位,从1开始遍历
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现