每日OJ题_两个数组dp⑧_力扣718. 最长重复子数组

发布于:2024-04-14 ⋅ 阅读:(85) ⋅ 点赞:(0)

目录

力扣718. 最长重复子数组

解析代码


力扣718. 最长重复子数组

718. 最长重复子数组

难度 中等

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

示例 1:

输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
输出:3
解释:长度最长的公共子数组是 [3,2,1] 。

示例 2:

输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
输出:5

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 100
class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {

    }
};

解析代码

        子数组是数组中连续的⼀段,习惯上以某一个位置为结尾来研究。由于是两个数组, 因此可以尝试:以第一个数组的 i 位置为结尾以及第二个数组的 j 位置为结尾来解决问题。

状态表示:

        结合题目得到:dp[i][j] 表示以第一个数组的 i 位置为结尾,以及第二个数组的 j 位置为结尾公共的 、长度最长的子数组的长度。

状态转移方程:

        对于 dp[i][j] ,当 nums1[i] == nums2[j] 的时候,此时最长重复子数组的长度应该等于 1 加上除去最后一个位置时,以 i - 1, j - 1 为结尾的最长重复子数组的长度。 因此,状态转移方程为: dp[i][j] = 1 + dp[i - 1][j - 1],nums1[i] != nums2[j] 时 为 0,所以可以初始化dp表为0。

初始化:

        为了处理越界的情况,可以添加一行和一列, dp 数组的下标从 1 开始,这样就无需初始化。 第一行表示第⼀个数组为空,此时没有重复子数组,因此里面的值设置成 0 即可, 第一列也是同理。

填表顺序:从上往下填写每一行,每一行从左往右。

最后返回dp表的最大值。

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size(), n = nums2.size(), ret = 0;
        vector<vector<int>> dp(m + 1,vector<int>(n + 1, 0));
        //dp[i][j] 表示以第一个数组的 i 位置为结尾,
        // 以及第二个数组的 j 位置为结尾公共的 、长度最长的子数组的长度。
        for(int i = 1; i <= m; ++i)
        {
            for(int j = 1; j <= n; ++j)
            {
                if(nums1[i - 1] == nums2[j - 1]) // 注意原数组下标映射
                {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    ret = max(ret, dp[i][j]);
                }
            }
        }
        return ret;
    }
};


网站公告

今日签到

点亮在社区的每一天
去签到