Leetcode | Maximum Length of Repeated Subarray

718. Maximum Length of Repeated Subarray

Given two integer arrays A and B, return the maximum length of an subarray that appears in both arrays.

Example 1:

Input:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
Output: 3
Explanation: 
The repeated subarray with maximum length is [3, 2, 1].

Note:

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

! subarray, not subsequence

  • I. DP,
    1. Similar to LCS
    2. Time Complexity: O( LA x LB )
    3. Space Complexity: O( LA x LB )
//c++
class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int l = A.size(),ans = 0;
        vector<vector<int>> dp(l,vector<int>(l,0));
        for (int i=0;ifor (int j=0;jif(i == 0 || j == 0) dp[i][j] = (A[i]==B[j]);
                else dp[i][j] = (A[i]==B[j]) ? dp[i-1][j-1]+1:0;
                ans = max(ans,dp[i][j]);
            }
        }
        return ans;
    }
};
  • II. Optimization
    1. DP
    2. Time Complexity: O( LA x LB )
    3. Space Complexity: O( LA )
//c++
class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int m = A.size();
        int n = B.size();
        vector<int> dp(n + 1);
        int result = 0;
        for (int i = 1; i <= m; ++i) {
            vector<int> ndp(n + 1);
            for (int j = 1; j <= n; ++j) {
                if (A[i-1] == B[j-1]) {
                    ndp[j] = dp[j-1] + 1;
                    result = max(ndp[j], result);
                }
            }
            dp = ndp;
        }
        return result;
    }
};
  • III. Optimization 2
    1. DP
    2. Time Complexity: O( LA x LB )
    3. Space Complexity: O(1)
      since dp[i][j] only depends on dp[i-1][j-1], we only need to keep it and traverse the matrix diagonally.
//Java
public int findLength(int[] A, int[] B) {
        int maxLen = 0;      
        for (int j = 0; j < B.length; j++) {
            int maxLenEnding = 0;
            for (int i = 0, k = j; i < A.length && k < B.length; i++, k++) {
                if (A[i] != B[k]) maxLenEnding = 0;
                else {
                    maxLenEnding++;
                    maxLen = Math.max(maxLen, maxLenEnding);
                }
            }
        }

        for (int i =1; i < A.length; i++) {
            int maxLenEnding = 0;
            for (int j = 0, k = i; k < A.length && j < B.length; j++, k++) {
                if (A[k] != B[j]) maxLenEnding = 0;
                else {
                    maxLenEnding++;
                    maxLen = Math.max(maxLen, maxLenEnding);
                }
            }
        }
        return maxLen;  
    }
  • IV. HashMap
//c++
struct Node {
  int len;
  Node *ch[101], *f;
  Node() : len(0), f(NULL) { memset(ch, 0, sizeof ch); }
};
struct SAM {
  Node *last, *root;
  SAM() { root = last = new Node(); };
  void add(int c) {
    Node *e = new Node(), *tmp = last;
    e->len = last->len + 1;
    for (; tmp && !tmp->ch[c]; tmp = tmp->f)
      tmp->ch[c] = e;
    if (!tmp) {
      e->f = root;
    } else {
      Node *nxt = tmp->ch[c];
      if (tmp->len + 1 == nxt->len)
        e->f = nxt;
      else {
        Node *np = new Node();
        *np = *nxt;
        np->len = tmp->len + 1;
        nxt->f = e->f = np;
        for (; tmp && tmp->ch[c] == nxt; tmp = tmp->f)
          tmp->ch[c] = np;
      }
    }
    last = e;
  }
};

class Solution {
public:
  int findLength(vector<int> &A, vector<int> &B) {
    SAM a = SAM();
    for (int x : A) a.add(x);
    int ans = 0, cur = 0;
    Node *t = a.root;
    for (int i = 0; i < B.size() && t; ++i) {
      int idx = B[i];
      while (t != a.root && !t->ch[idx]) {
        t = t->f;
        cur = t->len;
      }
      if (t->ch[idx]) {
        t = t->ch[idx];
        cur++;
      }
      if (cur > ans)
        ans = cur;
    }
    return ans;
  }
};

相关题目

  • 115. Distinct Subsequences
    count the number of distinct subsequences of S which equals T
    DP, O(n) space
class Solution {
public:
    int numDistinct(string s, string t) {
        int l1 = s.length(), l2 = t.length(), tmp, pre;
        vector<int> dp(l2+1,0);
        dp[0] = 1;
        for (int i=1;i<=l1;i++){
            pre = 1;
            for (int j=1;j<=l2;j++){
                tmp = dp[j];
                dp[j] = dp[j] + (s[i-1]==t[j-1] ? pre:0);
                pre = tmp;
            }
            cout << endl;
        }
        return dp[l2];
    }
};
  • 最大连续子序列和,乘积,最长递增子串,最长公共子串,子序列等问题(动态规划等)
  • Some programs are online.

你可能感兴趣的:(算法,Leetcode,leetcode)