718. 最长重复子数组;424. 替换后的最长重复字符

    技术2022-07-10  148

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

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

    class Solution {动态二维+无伪头行列 public: int findLength(vector<int>& A, vector<int>& B) { if(A.size()==0||B.size()==0)return 0; vector<vector<int>>dp(A.size(),vector<int>(B.size(),0)); int resMax=0; for(int j=0;j<B.size();++j) dp[0][j]=A[0]==B[j]?1:0; for(int i=1;i<A.size();++i){ dp[i][0]=A[i]==B[0]?1:0; for(int j=1;j<B.size();++j) if(A[i]==B[j]){ dp[i][j]=dp[i-1][j-1]+1; resMax=max(resMax,dp[i][j]); } } return resMax; } }; class Solution {//动态一维优化+无伪头行列 public: int findLength(vector<int>& A, vector<int>& B) { if(A.size()==0||B.size()==0)return 0; vector<int>dp(B.size(),0); int resMax=0; for(int i=0;i<B.size();++i) if(A[0]==B[i])dp[i]=1; for(int i=1;i<A.size();++i){ for(int j=B.size()-1;j>=1;--j)//逆序 j:b.size()-1~1 if(A[i]==B[j]){ dp[j]=dp[j-1]+1; resMax=max(resMax,dp[j]); } else dp[j]=0;//容易漏掉 dp[0]=A[i]==B[0]?1:0;//j:0 resMax=max(resMax,dp[0]); } return resMax; } }; class Solution {//动态二维+伪头行列 public: int findLength(vector<int>& A, vector<int>& B) { if(A.size()==0||B.size()==0)return 0; vector<vector<int>>dp(A.size()+1,vector<int>(B.size()+1,0)); int resMax=0; for(int i=1;i<=A.size();++i) for(int j=1;j<=B.size();++j) if(A[i-1]==B[j-1]){ dp[i][j]=dp[i-1][j-1]+1; resMax=max(resMax,dp[i][j]); } return resMax; } }; class Solution {//动态一维+伪头 public: int findLength(vector<int>& A, vector<int>& B) { if(A.size()==0||B.size()==0)return 0; vector<int>dp(B.size()+1,0);// int resMax=0; for(int i=1;i<=B.size();++i) if(A[0]==B[i-1])dp[i]=1; for(int i=2;i<=A.size();++i) for(int j=B.size();j>=1;--j) if(A[i-1]==B[j-1]){ dp[j]=dp[j-1]+1; resMax=max(resMax,dp[j]); } else dp[j]=0;// return resMax; } };

     

    给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。

    注意: 字符串长度 和 k 不会超过 104。

    示例 1:

    输入: s = "ABAB", k = 2

    输出: 4

    解释: 用两个'A'替换为两个'B',反之亦然。

    示例 2:

    输入: s = "AABABBA", k = 1

    输出: 4

    解释: 将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。 子串 "BBBB" 有最长重复字母, 答案为 4。

    class Solution { public: int characterReplacement(string s, int k) { if(s.size()<=1)return s.size(); unordered_map<char,int>windows; int le=0,ri=0; int maxCnt=0; int res=0; while(ri<s.size()){ char c=s[ri++]; ++windows[c]; maxCnt=max(maxCnt,windows[c]); if(ri-le<=maxCnt+k)res=max(res,ri-le); if(ri-le>maxCnt+k){ char c=s[le++]; if(windows[c]--==maxCnt)--maxCnt; } } return res; } }; 为什么maxCnt减小时可以不更新。 right++时,窗口扩大, left++,right++时,窗口大小不变,窗口平移。 可以看出 窗口并不会缩小。 代码最终返回的结果是最大的窗口大小,我们找的是最大的窗口,只有maxCnt变大,窗口才可以扩大;maxCnt减小对窗口的大小没有什么影响,所以不更新也可以。

     

    Processed: 0.021, SQL: 9