leetcode滑动窗口题模板

模板来源见:https://www.bilibili.com/video/BV1V44y1s7zJ?spm_id_from=444.41.header_right.fav_list.click

具体模板如下:

在这里插入图片描述
解释:
①这里的result相当于判断条件,比如不相同的元素个数=2;窗口中的元素个数=某字符串长度。
②bestResult指需要返回的结果,通常是长度,如果要返回字符串的话另外设置两个变量begin和end记录符合条件的数组下标,不然在窗口移动的时候left和right会变得面目全非。
③最长/最短模板的区别和联系在于:当result满足条件时一定要及时更新返回值。

代入做题:

159至多包含两个不同字符的最长子串:
在这里插入图片描述

class Solution {
public:
    int lengthOfLongestSubstringTwoDistinct(string s) {
        unordered_map<char,int> ooc;
        int left=0,right=0,ans=0;
        int cnt=0;
        while(right<s.size()){
             if(ooc[s[right]]==0) cnt++;
              ooc[s[right]]++;
              while(cnt>2){
                    ooc[s[left]]--;
                    if(ooc[s[left]]==0) cnt--;
                    left++;
              }
              ans=max(ans,right-left+1);
              right++;
        }
        return ans;

    }
};

3.无重复字符的最长子串
在这里插入图片描述

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int>ooc;
        int left=0,right=0,len=0;
        while(right<s.size())
        {
            ooc[s[right]]++;
            while(ooc[s[right]]>=2)//为什么用s[right]判断,是因为前面的元素肯定至多出现一次
            {
                ooc[s[left]]--;
                left++;
           }
           len=max(len,right-left+1);
           right++;
        }
        return len;
    }
};

209.长度最小的子数组
在这里插入图片描述

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
       int left=0,right=0,current=0,len=INT_MAX;
       while(right<nums.size()){
             current+=nums[right];
             while(current>=target){
                  len=min(len,right-left+1);
                  current-=nums[left];
                  left++;

             }
          right++;
       }
       if(len==INT_MAX) return 0;
       return len;
    }
};

76.最小覆盖子串
在这里插入图片描述

class Solution {
public:
    string minWindow(string s, string t) {
        int begin=0,end=0;
        int left=0,right=0,numfound=0;
        int minlen=INT_MAX;
        unordered_map<char,int> hashs; //hashs记录s中滑动窗口对应的hash表
        unordered_map<char,int> hasht;//hasht记录t中字符出现的数量,注意可以重复,例如t=ABCC
        for(int i=0;i<t.size();i++)
        hasht[t[i]]++;
        string ans;
        while(right<s.size()){
           hashs[s[right]]++;
           if(hashs[s[right]]<=hasht[s[right]])//说明找到了正好需要的元素
           numfound++;
           while(numfound==t.size()){
               if(right-left+1<minlen){
                    minlen=right-left+1;
                    begin=left;
                    end=right;

               }//接下,而在此条件中滑动窗口中的t中字符数量必然>=t中字符数量,因为已经满足numfound=t.size()了,所以直接用==判断
               if(hashs[s[left]]==hasht[s[left]]) //举个例子 s=AOCCCDEBACFGB t=ABCC 那左指针扫到CCC中第一个C时其实numfound不用--的
               numfound--;
               hashs[s[left]]--;
               left++;
              }
        right++;
        }
    if(minlen==INT_MAX) return "";
    return s.substr(begin,minlen);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值