帕先生之最长公共子数组LeetCode 718

60 阅读1分钟

1、题目描述

给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度

2、动态规划解题思路

1、dp数组的定义: dp[i][j]表示了以i-1与j-1号元素作为结尾的公共子数组的长度. 即 公共子数组的结尾必须是i-1和j-1, 所以,当i-1 != j-1 时, dp[i][j]=0, 如果相同 dp[i][j] = dp[i-1][j-1]+1

2、递推公式:

如果nums1[i1]==num2[j1]:dp[i][j]=dp[i1][j1]+1如果 nums1[i-1] == num2[j-1]: dp[i][j] = dp[i-1][j-1] + 1

因为是子数组, 连续的, 所以一定是由dp[i-1][j-1]推导而来

3、初始化:

因为dp是以i-1j-1结尾来计算的, 所以dp[i][0] 表示的是nums1[i-1]nums2[0-1]的元素, 索引为负, 没有意义, 所以初始化为0, dp[0][j]也是同理, 其余值, 因为求长度, 所以默认全部初始化为0

dp[nums1.length]代表的是nums1[length-1]

遍历的时候这里的i < nums1.length+1

3、 代码实现

class Solution:
    def findLength(self, nums1: List[int], nums2: List[int]) -> int:
        result = 0
        dp = [ [ 0 for j in range(len(nums2)+1)] for i in range(len(nums1)+1)]
        # 这里是nums[i-1] 所以i从1开始,i最大为length
        for i in range(1, len(nums1)+ 1):
            for j in range(1, len(nums2)+1):
                # dp数组的定义是以i-1和j-1结尾的公共子数组长度, 所以这里判断i-1和j-1
                if nums1[i-1] == nums2[j-1]:
                  dp[i][j] = dp[i-1][j-1] + 1
                  # 同时计算最值
                  result = max(dp[i][j], result)
        return result