LeetCode 6924. 最长合法子字符串的长度(双指针)

问题描述:

在这里插入图片描述
|在这里插入图片描述

解法:
这题有个需要注意的点是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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值