From 8fb169701478cce21d5bfba761289479a0e27fbd Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Wed, 7 Jun 2023 05:26:40 -0500 Subject: [PATCH] =?UTF-8?q?Update=200718.=E6=9C=80=E9=95=BF=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E5=AD=90=E6=95=B0=E7=BB=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0718.最长重复子数组.md | 96 +++++++++++++++++++++----- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/problems/0718.最长重复子数组.md b/problems/0718.最长重复子数组.md index 08be6732..78ef7ddd 100644 --- a/problems/0718.最长重复子数组.md +++ b/problems/0718.最长重复子数组.md @@ -247,37 +247,99 @@ class Solution { Python: -> 动态规划: +2维DP ```python class Solution: - def findLength(self, A: List[int], B: List[int]) -> int: - dp = [[0] * (len(B)+1) for _ in range(len(A)+1)] + def findLength(self, nums1: List[int], nums2: List[int]) -> int: + # 创建一个二维数组 dp,用于存储最长公共子数组的长度 + dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)] + # 记录最长公共子数组的长度 result = 0 - for i in range(1, len(A)+1): - for j in range(1, len(B)+1): - if A[i-1] == B[j-1]: - dp[i][j] = dp[i-1][j-1] + 1 - result = max(result, dp[i][j]) + + # 遍历数组 nums1 + for i in range(1, len(nums1) + 1): + # 遍历数组 nums2 + for j in range(1, len(nums2) + 1): + # 如果 nums1[i-1] 和 nums2[j-1] 相等 + if nums1[i - 1] == nums2[j - 1]: + # 在当前位置上的最长公共子数组长度为前一个位置上的长度加一 + dp[i][j] = dp[i - 1][j - 1] + 1 + # 更新最长公共子数组的长度 + if dp[i][j] > result: + result = dp[i][j] + + # 返回最长公共子数组的长度 return result + ``` -> 动态规划:滚动数组 +1维DP ```python class Solution: - def findLength(self, A: List[int], B: List[int]) -> int: - dp = [0] * (len(B) + 1) + def findLength(self, nums1: List[int], nums2: List[int]) -> int: + # 创建一个一维数组 dp,用于存储最长公共子数组的长度 + dp = [0] * (len(nums2) + 1) + # 记录最长公共子数组的长度 result = 0 - for i in range(1, len(A)+1): - for j in range(len(B), 0, -1): - if A[i-1] == B[j-1]: - dp[j] = dp[j-1] + 1 + + # 遍历数组 nums1 + for i in range(1, len(nums1) + 1): + # 用于保存上一个位置的值 + prev = 0 + # 遍历数组 nums2 + for j in range(1, len(nums2) + 1): + # 保存当前位置的值,因为会在后面被更新 + current = dp[j] + # 如果 nums1[i-1] 和 nums2[j-1] 相等 + if nums1[i - 1] == nums2[j - 1]: + # 在当前位置上的最长公共子数组长度为上一个位置的长度加一 + dp[j] = prev + 1 + # 更新最长公共子数组的长度 + if dp[j] > result: + result = dp[j] else: - dp[j] = 0 #注意这里不相等的时候要有赋0的操作 - result = max(result, dp[j]) + # 如果不相等,将当前位置的值置为零 + dp[j] = 0 + # 更新 prev 变量为当前位置的值,供下一次迭代使用 + prev = current + + # 返回最长公共子数组的长度 return result + ``` +2维DP 扩展 +```python +class Solution: + def findLength(self, nums1: List[int], nums2: List[int]) -> int: + # 创建一个二维数组 dp,用于存储最长公共子数组的长度 + dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)] + # 记录最长公共子数组的长度 + result = 0 + # 对第一行和第一列进行初始化 + for i in range(len(nums1)): + if nums1[i] == nums2[0]: + dp[i + 1][1] = 1 + for j in range(len(nums2)): + if nums1[0] == nums2[j]: + dp[1][j + 1] = 1 + + # 填充dp数组 + for i in range(1, len(nums1) + 1): + for j in range(1, len(nums2) + 1): + if nums1[i - 1] == nums2[j - 1]: + # 如果 nums1[i-1] 和 nums2[j-1] 相等,则当前位置的最长公共子数组长度为左上角位置的值加一 + dp[i][j] = dp[i - 1][j - 1] + 1 + if dp[i][j] > result: + # 更新最长公共子数组的长度 + result = dp[i][j] + + # 返回最长公共子数组的长度 + return result + + +``` Go: ```Go func findLength(A []int, B []int) int {