718、最长的重复数组

  1. 718、最长的重复数组
    1. 示例:
  2. 题解
    1. 1、暴力
    2. 2、动态规划
    3. 3、滑动窗口
    4. 4、二分查找 + 哈希

718、最长的重复数组

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

 

示例:

输入:
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、暴力

class Solution {
    public int findLength(int[] A, int[] B) {
        int max = 0;
        for (int i = 0;i < A.length;i++) {
            for (int j = 0;j < B.length;j++) {
                if (A[i] == B[j]) {
                    int count = 1;
                    for (int k = 1; k < Math.min(A.length - i,B.length - j);k++) {
                        if (A[i + k] == B[j + k]) {
                            count++;
                        } else {
                            break;
                        }
                    }
                    max = Math.max(count,max);
                }
            }
        }
        return max;
    }
}

2、动态规划

dp[i][j] 表示A[i:] 和 B[j:]最长公共前缀

class solution {
    public int findLength(int[] A,int[] B) {
        int n = A.length, m = B.length;
        int[][] dp = new int[n + 1][m + 1];
        int max = 0;
        for (int i = n - 1;i >= 0;i--) {
            for (int j = m - 1;j >= 0;j--) {
                // 自顶而下
                dp[i][j] = A[i]== B[j] ? dp[i + 1][j + 1] + 1 : 0;
                max = Math.max(max,dp[i][j]);
            }
        }
        return max;
    }
}

3、滑动窗口

class Solution {
    public int findLength(int[] A, int[] B) {
        int n = A.length, m = B.length;
        int ret = 0;
        for (int i = 0; i < n; i++) {
            int len = Math.min(m, n - i);
            int maxlen = maxLength(A, B, i, 0, len);
            ret = Math.max(ret, maxlen);
        }
        for (int i = 0; i < m; i++) {
            int len = Math.min(n, m - i);
            int maxlen = maxLength(A, B, 0, i, len);
            ret = Math.max(ret, maxlen);
        }
        return ret;
    }

    public int maxLength(int[] A, int[] B, int addA, int addB, int len) {
        int ret = 0, k = 0;
        for (int i = 0; i < len; i++) {
            if (A[addA + i] == B[addB + i]) {
                k++;
            } else {
                k = 0;
            }
            ret = Math.max(ret, k);
        }
        return ret;
    }
}

// 作者:LeetCode-Solution
// 链接:https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/solution/zui-chang-zhong-fu-zi-shu-zu-by-leetcode-solution/

4、二分查找 + 哈希

class Solution {
    int mod = 1000000009;
    int base = 113;

    public int findLength(int[] A, int[] B) {
        int left = 1, right = Math.min(A.length, B.length) + 1;
        while (left < right) {
            int mid = (left + right) >> 1;
            if (check(A, B, mid)) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left - 1;
    }

    public boolean check(int[] A, int[] B, int len) {
        long hashA = 0;
        for (int i = 0; i < len; i++) {
            hashA = (hashA * base + A[i]) % mod;
        }
        Set<Long> bucketA = new HashSet<Long>();
        bucketA.add(hashA);
        long mult = qPow(base, len - 1);
        for (int i = len; i < A.length; i++) {
            hashA = ((hashA - A[i - len] * mult % mod + mod) % mod * base + A[i]) % mod;
            bucketA.add(hashA);
        }
        long hashB = 0;
        for (int i = 0; i < len; i++) {
            hashB = (hashB * base + B[i]) % mod;
        }
        if (bucketA.contains(hashB)) {
            return true;
        }
        for (int i = len; i < B.length; i++) {
            hashB = ((hashB - B[i - len] * mult % mod + mod) % mod * base + B[i]) % mod;
            if (bucketA.contains(hashB)) {
                return true;
            }
        }
        return false;
    }
    
    // 使用快速幂计算 x^n % mod 的值
    public long qPow(long x, long n) {
        long ret = 1;
        while (n != 0) {
            if ((n & 1) != 0) {
                ret = ret * x % mod;
            }
            x = x * x % mod;
            n >>= 1;
        }
        return ret;
    }
}

// 作者:LeetCode-Solution
// 链接:https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/solution/zui-chang-zhong-fu-zi-shu-zu-by-leetcode-solution/

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

💰

Title:718、最长的重复数组

Count:750

Author:攀登

Created At:2020-07-26, 00:19:44

Updated At:2024-06-15, 15:52:32

Url:http://jiafeimao-gjf.github.io/2020/07/26/718%E3%80%81%E6%9C%80%E9%95%BF%E7%9A%84%E9%87%8D%E5%A4%8D%E6%95%B0%E7%BB%84/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

×

Help us with donation