leetcode718(最长重复子数组)--Java语言实现

夙愿已清 提交于 2020-08-10 13:25:51

求:

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

示例 1:

输入:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
输出: 3
解释: 
长度最长的公共子数组是 [3, 2, 1]。
说明:

1 <= len(A), len(B) <= 1000
0 <= A[i], B[i] < 100

题目链接: https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/

解:

思路:

1、暴力破解

时间复杂度:O(N^3)

空间复杂度:O(1)

对A数组的每一次遍历,在B数组中寻找和A数组相同的元素,然后A、B同时向后寻找,如果相等当前最大长度+1,得到当次比对的最大长度。所有遍历完成后,每一趟遍历中的最大长度的最大者,就是总的最大长度。

public int findLength(int[] A, int[] B) {
    int maxLen = 0;
    for (int i = 0; i < A.length; i++) {
        for (int j = 0; j < B.length; j++) {
            int k = 0;
            while (i + k < A.length && j + k < B.length && A[i + k] == B[j + k]) ++k;
            if (k > maxLen) maxLen = k;
        }
    }
    return maxLen;
}

 

2、动态规划

我们记录上一次比对的结果,举例如A、B数组匹配到最大长度3,对应的匹配子数组是[3,2,1],则匹配[2,1]和[1]一定不会是最大的。且[3,2,1]的匹配可以复用[2,1]的结果,[2,1]可以复用[1]的结果。因此我们从后往前匹配,使用一个二维数组dp[][]来记录当前的匹配值。并得到状态转移方程:

dp[i][j]=dp[i+1][j+1]+1(A[i]==B[j])

dp[i][j]=0(A[i]!=B[j])

时间复杂度:O(M*N)
空间复杂度:O(M*N)
public int findLength(int[] A, int[] B) {
    int dp[][] = new int[A.length + 1][B.length + 1];
    int max =0;
    for (int i = A.length - 1; i >= 0; i--) {
        for (int j = B.length - 1; j >= 0; j--) {
            dp[i][j] = A[i] == B[j] ? dp[i + 1][j + 1] + 1 : 0;
            if(dp[i][j]>max) max=dp[i][j];
        }
    }
    return max;
}

 

3、其他解法,如滑动窗口(参考官方题解)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!