LeetCode热题(JS版) - 718. 最长重复子数组

187 阅读1分钟

题目描述

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

示例

输入:

const A = [1, 2, 3, 2, 1];
const B = [3, 2, 1, 4, 7];

输出:

3

解释:

长度最长的公共子数组是 [3, 2, 1]

思路

本题可采用动态规划来求解,可以将其转化为一个二维矩阵,具体实现如下:

  1. 初始化一个二维矩阵 dp,其中 dp[i][j] 表示以 A[i-1]B[j-1] 结尾的公共子数组的长度。
  2. A[i-1] === B[j-1] 时,说明当前元素可以加入公共子数组中,此时有 dp[i][j] = dp[i-1][j-1] + 1
  3. A[i-1] !== B[j-1] 时,说明当前元素不能加入公共子数组中,此时有 dp[i][j] = 0
  4. 在更新每个元素时,需要同时更新最长公共子数组的长度。
  5. 最后返回最长公共子数组的长度即可。

代码实现

function findLength(A: number[], B: number[]): number {
  const m = A.length;
  const n = B.length;
  let maxLen = 0;
  const dp: number[][] = Array.from({ length: m + 1 }, () =>
    Array.from({ length: n + 1 }, () => 0)
  );

  for (let i = 1; i <= m; i++) {
    for (let j = 1; j <= n; j++) {
      if (A[i - 1] === B[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;
        maxLen = Math.max(maxLen, dp[i][j]);
      } else {
        dp[i][j] = 0;
      }
    }
  }

  return maxLen;
}

image.png

时间复杂度

本题采用了动态规划来求解,时间复杂度为 O(mn)O(mn),其中 mmnn 分别为两个数组的长度。因为对于每个元素都需要计算一次,所以时间复杂度无法再优化。