滑动窗口问题记录

对于字符串或者数组,找到一个连续的区间,这个区间满足一定的条件。这样的问题就使用滑动窗口来解决,滑动窗口,从某种意义上属于动态规划算法,也使用了双指针。

滑动窗口的关键是确定窗口的两个边沿什么时候移动,什么条件下移动。一般情况下,窗口右边沿是一直向前移动,在移动的过程中根据判断条件来决定左边沿是不是需要移动。

1最小覆盖字符串

76. 最小覆盖子串 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    string minWindow(string s, string t) {
        //找一个范围,字符串或者数组,这样的问题,使用滑动窗口
        //滑动窗口,关键是窗口的两个边沿什么时候移动
        //一般情况下是,一个边沿直接移动
        //另外一个在特定条件下移动
        //1、首先计算t字符串每个字符出现的次数
        //2、然后遍历s字符串,看计数,然后增加count,移动右边沿
        //3、什么时候移动左边沿呢,count和t的长度相同的时候,这个字符串就是一个预期的结果
        for (char oneC : t) {
            tCharCount[oneC]++;
        }

        int left = 0;
        int right = 0;
        for (right = 0; right < s.size(); right++) {
            sCharCount[s[right]]++;
            
            //为什么是<=,而不是<,因为sCharCount[s[right]]在上边已经++了
            if (sCharCount[s[right]] <= tCharCount[s[right]]) {
                count++;
            }

            while (sCharCount[s[left]] > tCharCount[s[left]]) {
                sCharCount[s[left]]--;
                left++;
            }

            if (count == t.size()) {
                if (ret.empty() || right - left + 1 < ret.size()) {
                    ret = s.substr(left, right - left + 1);
                }
            }
        }
        return ret;
    }

    int tCharCount[123] = {0};
    int sCharCount[123] = {0};
    int count = 0;
    std::string ret = "";
};

2无重复字符的最长子串

3. 无重复字符的最长子串 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //最基本的方法
        //长度从大到小遍历字符串,看是不是有重复,有重复继续进行
        //没有重复直接返回

        //滑动窗口
        //右边沿直接滑动
        //用map保存字符所在的索引,如果已经存在了,说明重复了,移动left
        
        int ret = 0;
        int size = s.size();
        int left = 0;
        int right = 0;
        std::map<char, int> charIndex;
        for (; right < size; right++) {
          if (charIndex.find(s[right]) != charIndex.end()) {
            //这个判断条件很容易忘
            if (left < charIndex[s[right]] + 1) {
              left = charIndex[s[right]] + 1;
            }

          }
          //这行很容易忘
          charIndex[s[right]] = right;
          
          ret = (right - left + 1) > ret ? (right - left + 1) : ret;
        }
        return ret;
    }
};

3无重复字符的最长子串

3. 无重复字符的最长子串 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        //有边沿一直向前走
        //用一个sum记录和
        //当和大于等于target,移动left
        //ret初始值初始化为0
        int len = nums.size();
        int left = 0;
        int right = 0;
        int sum = 0;
        int ret = 1000000;
        for (; right < len; right++) {
            sum += nums[right];
            // >= 而不是 >,因为结果都是在这里计算的
            while (sum >= target) {
                ret = right - left + 1 < ret ? right - left + 1 : ret;
                sum -= nums[left];
                left++;
            }
        }

        return ret == 1000000 ? 0 : ret;
    }
};
相关推荐
ShineWinsu3 小时前
对于C++:C++20中线程、初始化、Lambda与内存视图等特性的解析
c++·c++20
张张的快乐时光呀!4 小时前
记录使用 MFC 打开文件对话框读取一张图片并做简单的灰度转换算法简单学习过程
c++·mfc
东华万里5 小时前
第41篇 C++类与对象核心知识梳理:从底层原理到面试实战
开发语言·c++·大学生专区
qq_589666056 小时前
C语言、C++与C#的区别详解
c语言·c++·c#
万法若空7 小时前
排列组合恒等式
c++·算法
老洋葱Mr_Onion8 小时前
【C++】CSP-J初赛模拟卷七错题整理(作者自用)
c++·算法·深度优先
电商API_180079052478 小时前
速卖通商品采集API技术文章
java·开发语言·c++·api·跨境电商·商品详情
汉克老师9 小时前
CSP-J 初赛(以满分为目标):第四课《看懂计算机到底在算什么!——C++变量、表达式和运算符 》
c++·小学生·学c++编程
小小龙学IT9 小时前
zstd(Zstandard)开源压缩库实战指南:让数据又快又小
c++·开源
小小龙学IT10 小时前
GLM 开源图形学数学库深度解析:从向量、矩阵到四元数的完整实战
c++·矩阵·开源·mfc