最长重复子数组

时间:2022-07-22
本文章向大家介绍最长重复子数组,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

问题描述:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解决方案:

​ 模板题直接上dp,dp[i] [j] 为A数组以 i 结尾,B数组以 j 结尾的最长公共子串长度。

​ 传递函数:

dp[i][j] = begin{cases}0 qquadqquad qquad qquad quad A[i] != B[j] \ dp[i - 1][j - 1] + 1 qquad elseend{cases}

​ 若当前A[i] 不等于 B[j]时,以A[i]结尾和以B[j]结尾的最长公共子串长度一定为0,若其相等时dp[i] [j] 取值等于dp[i] [j] 取值加1.

​ baseline:

​ 我们发现当前位置的值依赖于其上边的值和其左边的值,因此初始化时只需填完第一行和第一列的值即可。

dp[i][0] = begin{cases}1 qquad A[i] = B[0] \ 0 qquad elseend{cases}

dp[0][j] = begin{cases}1 qquad A[0] = B[j] \ 0 qquad elseend{cases}

​ 实现代码如下:

class Solution {
    public int findLength(int[] A, int[] B) {
        int M = A.length, N = B.length;
        int[][] dp = new int[M][N]; // dp[i][j] 表示A以i结尾 B以j结尾的最长公共子串的长度
        int max = 0;
        for(int j = 0; j < N; j++){
            if(B[j] == A[0]){
                dp[0][j] = 1;
                max = 1;
            }
        }
        for(int i = 0; i < M; i++){
            if(A[i] == B[0]){
                dp[i][0] = 1;
                max = 1;
            }
        }
        for(int i = 1; i < M; i++){
            for(int j = 1; j < N; j++){
                if(A[i] == B[j]){
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }
                max = Math.max(dp[i][j], max);
            }
        }
        return max;
    }
}