• 718. 最长重复子数组


    718. 最长重复子数组

    题目链接: 718. 最长重复子数组(中等)

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

    示例 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

    解题思路

    题目中说的子数组,其实就是连续子序列。运用动态规划来解答。

    C++

    class Solution {
    public:
        int findLength(vector<int>& nums1, vector<int>& nums2) {
            // 1. dp数组的含义
            // dp[i][j] :以下标i - 1为结尾的 nums1,和以下标j - 1为结尾的 nums2,最长重复子数组长度为dp[i][j]
            // 注意:在遍历dp[i][j]的时候i 和 j都要从1开始的,这就减轻了初始化dp数组的工作
            // 2. 初始化
            // 根据dp[i][j]的定义,dp[i][0] 和dp[0][j]其实都是没有意义的!它们是为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;
            // 所以dp[i][0] 和dp[0][j]初始化为0。
            vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0));
            int result = 0; // 记录dp[i][j]的最大值
            // 4. 遍历顺序:外层for循环遍历 nums1,内层for循环遍历 nums2。
            for (int i = 1; i <= nums1.size(); i++) {
                for (int j = 1; j <= nums2.size(); j++) {
                    if (nums1[i - 1] == nums2[j - 1]) {
                        // 2.递推公式
                        // 根据dp[i][j]的定义,dp[i][j]的状态只能由dp[i - 1][j - 1]推导出来。
                        // 即当nums1[i - 1] 和 nums2[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1;
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    }
                    result = dp[i][j] > result ? dp[i][j] : result;
                }
            }
            return result;
        }
    };

    JavaScript

    /**
     * @param {number[]} nums1
     * @param {number[]} nums2
     * @return {number}
     */
    var findLength = function(nums1, nums2) {
        const dp = Array(nums1.length + 1).fill().map(item => Array(nums2.length + 1).fill(0));
        let result;
        for (let i = 1; i <= nums1.length; i++) {
            for (let j = 1; j <= nums2.length; j++) {
                if (nums1[i - 1] === nums2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }
                result = result > dp[i][j] ? result : dp[i][j];
            }
        }
        return result;
    };
    • 时间复杂度:O(n × m),n 为nums1长度,m为muns2长度

    • 空间复杂度:O(n × m)

  • 相关阅读:
    hdu2438 三分
    hdu3786 找出直系亲属 水题
    hdu3786 找出直系亲属 水题
    hdu4561 连续最大积
    hdu4561 连续最大积
    hdu4604 不错的子序列问题
    hdu4604 不错的子序列问题
    hdu4450 不错的贪心
    hdu1722 切蛋糕
    hdu3768 spfa+全排列
  • 原文地址:https://www.cnblogs.com/wltree/p/16008295.html
Copyright © 2020-2023  润新知