zoukankan      html  css  js  c++  java
  • 滑动窗口总结

    滑动窗口大致思路

    1.我们使用双指针的思路,初始定义两个指针,left=right=0,把索引闭区间[left,right]看作一个滑动窗口

    2.然后不断增加right的值,直到窗口中的字符串符合要求

    3.然后,停止增加right的值,转而增加left的值,直到窗口中的字符串不符合要求,每次增加left,就要更新一轮结果。

    4.不断重复2,3步骤,直到遍历完整个字符串

    通俗来讲,第2步是为了找到可行解,然后第三步是为了“优化可行解”。

    滑动窗口的窗口大小可能固定,也可能不固定。

    窗口大小固定代码模板:

    // 固定窗口大小为 k
        string s;
        // 在 s 中寻找窗口大小为 k 时的所包含最大元音字母个数
        int  right = 0;
        while(right < s.size()) {
            window.add(s[right]);
            right++;
            // 如果符合要求,说明窗口构造完成,
            if (right>=k) {
                // 这是已经是一个窗口了,根据条件做一些事情
               // ... 可以计算窗口最大值等 
                // 最后不要忘记把 right -k 位置元素从窗口里面移除
            }
        }
        return res;
    
    

    窗口大小不固定代码模板:

        string s, t;
            // 在 s 中寻找 t 的「最小覆盖子串」
        int left = 0, right = 0;
        string res = s;
    
        while(right < s.size()) {
            window.add(s[right]);
            right++;
            // 如果符合要求,说明窗口构造完成,移动 left 缩小窗口
            while (window 符合要求) {
                // 如果这个窗口的子串更短,则更新 res
                res = minLen(res, window);
                window.remove(s[left]);
                left++;
            }
        }
        return res;
    

    例题:

    1. 无重复字符的最长子串(https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/)

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            unordered_set<char>res;
            int n = s.length();
            int rk=-1,ans=0;
            for(int i=0;i<n;i++){
                if(i!=0){
                    res.erase(s[i-1]);
                }
                while(rk+1<n && ! res.count(s[rk+1])){
                    rk++;
                    res.insert(s[rk]);
                }
                ans=max(ans,rk-i+1);
            }
            return ans;
        }
    };
    
    
    1. 串联所有单词的子串(https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/)

    给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

    注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

    class Solution {
    public:
        vector<int> findSubstring(string s, vector<string>& words) {
            vector<int>ans;
            if(s.length() == 0 || words.size() == 0) return ans;
            int n = s.length();//字符串长度
            int len = words[0].length();//一个单词的长度
            int count = words.size();//单词个数
            int sum_len = count*len;//单词总长度
            unordered_map<string,int>mp; //统计每个单词出现的次数
            for(int i=0;i<words.size();i++){
                mp[words[i]]++;
            }
            for(int i=0;i<len;i++){
                int left=i,right=i;
                unordered_map<string,int>tmap;
                int cnt = 0;
                while(right+len<=n){ //截取是从right开始,故是小于等于
                    string tmp = s.substr(right,len);
                    right+=len;
                    if(mp.count(tmp)==0){ //若该单词未出现过
                        cnt=0;
                        left = right;
                        tmap.clear();
                    }
                    else { //单词出现过
                        tmap[tmp]++;
                        cnt++;
                        while(tmap[tmp]>mp[tmp]){ //重点部分,若该单词次数超了,说明在(left->right-len)之间一定有个字符串和tmp相等,因此从left开始截取字符串,舍掉超出的那部分
                            string t=s.substr(left,len);
                            tmap[t]--;
                            cnt--;
                            left+=len;
                        }
                        if(cnt == count) ans.push_back(left);
                    }
                    
                }
            }
            return ans;
        }
    };
    
    七月在野,八月在宇,九月在户,十月蟋蟀入我床下
  • 相关阅读:
    Linux常用命令-学习笔记
    Linux 输入输出重定向
    Linux 网卡配置参数
    JS Promise对象学习
    Linux用户身份与文件权限学习笔记
    4、点击事件
    3、自定义按压效果
    2、自定义背景形状
    1、文字大小,颜色
    5、跑马灯
  • 原文地址:https://www.cnblogs.com/voids5/p/14352912.html
Copyright © 2011-2022 走看看