Leetcode每日一题打卡

718. 最长重复子数组

原题
首先想到的就是暴力法:对数组A的遍历作为外循环,对数组B的遍历作为内循环,其中再嵌套while语句查找重复子数组,这样一来,时间复杂度为O(n^3),然后进行优化。
动态规划方法,在表m*n(其中m=A.size(),n=B.size())中,dp[i][j]取决于A[i]是否等于B[j],若等于,则dp[i][j]=dp[i-1][j-1]+1,否则就等于0。

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int m=A.size(), n=B.size();
        int ans=0;
        vector<vector<int>> dp(m+1, vector<int>(n+1,0));
        for(int i=m-1;i>=0;i--) {
            for(int j=n-1;j>=0;j--) {
                dp[i][j]=(A[i]==B[j]?dp[i+1][j+1]+1:0);
                ans=max(ans,dp[i][j]);
            }
        }
        return ans;
    }
};

时间复杂度和空间复杂度均为O(M*N)。
滑动窗口方法,使相同元素对齐来寻找最长重复子数组串。有两种对齐方式:B不动,A移动或者A不动,B移动,只需要在两种方式的遍历中找出最长子串即可,使用maxLength函数在对齐串的条件下查找最长子串。代码如下:

class Solution {
public:
    int maxLength(vector<int>&A, vector<int>&B, int index_A, int index_B, int len) {
        int res=0, k=0;
        for(int i=0;i<len;i++){
            if(A[index_A+i]==B[index_B+i]) k++;
            else k=0;
            res=max(res,k);
        }
        return res;
    }
    int findLength(vector<int>& A, vector<int>& B) {
        int ans=0;
        int m=A.size(), n=B.size();
        for(int i=0;i<m;i++) {
            int len=min(n,m-i);
            ans=max(ans, maxLength(A, B, i, 0, len));
        }
        for(int i=0;i<n;i++) {
            int len=min(m,n-i);
            ans=max(ans, maxLength(A, B, 0, i, len));
        }
        return ans;
    }
};

时间复杂度O((M+N)*min(M,N)),空间复杂度O(1)。

你可能感兴趣的:(Leetcode每日一题打卡,动态规划,leetcode,滑动窗口)