Leetcode每日一题打卡

    技术2022-07-10  131

    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)。

    Processed: 0.010, SQL: 9