718. 最長重複子數組;424. 替換後的最長重複字符

給兩個整數數組 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減小對窗口的大小沒有什麼影響,所以不更新也可以。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章