问题描述:
|
解法:
这题有个需要注意的点是forbidden[i].size() <= 10
考虑枚举右端点i,维护满足条件的最小左端点l
假设当前[l,i-1]符合条件,下一步在字串右侧新增s[i].
如果[l,i]不符合条件,那么不符合条件的子串一定包含s[i],
因此枚举j=[max(l,i-10+1),i],判断s[j,i]是否在forbidden[]中出现过.
如果出现过,则说明如果要包含s[i],那么左区间就必须>j才能满足条件,
因此更新l为max(l,j+1).
当l更新完后,此时[l,i]一定满足条件, 则令ans=max(ans,i-l+1)
ps:
感觉能用双指针的一类题,都有一个共性:
对于右端点i,如果选择的左端点l不满足条件,那么[1,l-1]就全部不满足条件。
Code:
class Solution {
public:
int longestValidSubstring(string s, vector<string>& bad) {
int ans=0;
int n=s.size();
map<string,int>mp;
for(auto i:bad){
mp[i]=1;
}
int l=0;
for(int i=0;i<n;i++){
string sub;
for(int j=i;j>=max(l,i-10+1);j--){
sub=s.substr(j,i-j+1);
if(mp.count(sub)){
// 不合法
// cout<<i<<' '<<sub<<endl;
l=j+1;
break;
}
// cout<<i<< ' '<<sub<<endl;
}
// cout<<i<<' '<<l<<endl;
if(i>=l){
ans=max(ans,i-l+1);
}
}
return ans;
}
};