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