Leetcode前端必会系列:最长重复子数组

77 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情

引言

算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。

题目描述

给两个整数数组 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

分析

根据题目的分析,我们如何设计求最长重复子数组的要求?很明显需要使用动态规划的设计去解决问题。

  1. 首先设计二维数组然后按照规律初始化二维数组的过程
  2. 接着需要我们从第二行第二列开始遍历二维数组,遍历的过程中按照动态规划求出最大的重复数组,不断地更新dp数组
  3. 最后标记返回地最大值就是目标结果。
  4. 返回结果。

解答

/**

 * @param {number[]} nums1

 * @param {number[]} nums2

 * @return {number}

 */

var findLength = function(nums1, nums2) {

  let len1 = nums1.length

  let len2 = nums2.length

  let max = 0

  let dp = Array.from(new Array(len1),item=>new Array(len2).fill(0))

  //dp[i][j] = dp[i-1][j-1]+1

  for(let i=0;i<len1;i++) {

    if(nums2[0] === nums1[i]) {

      dp[i][0] = 1

      max = 1

    }

  }

  for(let i=0;i<len2;i++) {

    if(nums1[0] === nums2[i]) {

      dp[0][i] = 1

      max = 1

    }

  }

  for(let i=1;i<len1;i++) {

    for(let j=1;j<len2;j++) {

      if(nums1[i]===nums2[j]) {

        dp[i][j] = dp[i-1][j-1] + 1

        max = Math.max(max,dp[i][j])

      }

    }

  }

  return max

};
   

根据代码,我们按照动态规划的设计思想就可以轻松的完成了设计过程了。