• 【基础算法】滑动窗口


    1.长度最小的子数组

    长度最小的子数组

    思路:

    滑动窗口四步-》

    1.进窗口

    2.判断

    3.出窗口

    4.更新结果-》这个更新结果的位置就题而定

    1. class Solution {
    2. public:
    3. int minSubArrayLen(int target, vector<int>& nums) {
    4. int ret = INT_MAX, sum = 0;
    5. for(int left = 0, right = 0; right < nums.size(); right++)
    6. {
    7. sum += nums[right]; //进窗口
    8. while(sum >= target)//判断
    9. {
    10. ret = min(ret, right - left + 1);
    11. sum -= nums[left++]; //出窗口
    12. }
    13. }
    14. return ret == INT_MAX ? 0 : ret;
    15. }
    16. };

    2.无重复字符的最长子串

    无重复字符的最长子串

    1. class Solution {
    2. public:
    3. int lengthOfLongestSubstring(string s) {
    4. int hash[128] = { 0 };
    5. int n = s.size();
    6. int left = 0, right = 0, ret = 0;
    7. while(right < n)
    8. {
    9. hash[s[right]]++;//进窗口
    10. while(hash[s[right]] > 1)//判断
    11. hash[s[left++]]--;//出窗口
    12. ret = max(ret, right - left + 1);//更新结果
    13. right++;
    14. }
    15. return ret;
    16. }
    17. };

    3.最大连续1的个数

     最大连续1的个数

    1. class Solution {
    2. public:
    3. int longestOnes(vector<int>& nums, int k) {
    4. int zero = 0;//记录0的个数
    5. int ret = 0;
    6. int n = nums.size();
    7. if(k >= n) return n; // 处理细节问题
    8. for(int left = 0, right = 0; right < n; right++)
    9. {
    10. if(nums[right] == 0) zero++;//进窗口
    11. while(zero > k)
    12. if(nums[left++] == 0) zero--;//出窗口
    13. ret = max(ret, right - left + 1); //更新结果
    14. }
    15. return ret;
    16. }
    17. };

    4.将x减到0的最小操作数

    将x减到0的最小操作数

    1. class Solution {
    2. public:
    3. int minOperations(vector<int>& nums, int x) {
    4. int len = -1, sum = 0, n = nums.size();
    5. for(int i : nums) sum += i;//数组的和
    6. int target = sum - x;
    7. if(target < 0) return -1; //处理细节问题
    8. for(int left = 0, right = 0, tmp = 0; right < n; right++)
    9. {
    10. tmp += nums[right]; //进窗口
    11. while(tmp > target)//判断,不判断等于target的原因:等于就找到了我们要的结果,无需再出窗口
    12. tmp -= nums[left++];//出窗口
    13. if(tmp == target) //更新结果
    14. len = max(len, right - left + 1);
    15. }
    16. if(len == -1) return len;
    17. else return n - len;
    18. }
    19. };

    5.水果成篮

    水果成篮

    1. class Solution {
    2. public:
    3. vector<int> findAnagrams(string s, string p) {
    4. int hash1[26] = { 0 };//记录p中的字符出现个数
    5. for(char ch : p) hash1[ch - 'a']++;
    6. int hash2[26] = { 0 };//记录窗口内的字符出现个数
    7. int m = p.size();
    8. vector<int> ret;
    9. for(int left = 0, right = 0, cnt = 0; right < s.size(); right++)
    10. {
    11. char in = s[right];//进窗口
    12. if(++hash2[in - 'a'] <= hash1[in - 'a']) cnt++;//cnt用来记录窗口中出现有效字符的个数
    13. if(right - left + 1 > m) //判断
    14. {
    15. //出窗口
    16. char out = s[left++];
    17. if(hash2[out - 'a']-- <= hash1[out - 'a']) cnt--;
    18. }
    19. if(cnt == m)
    20. ret.push_back(left);//更新结果
    21. }
    22. return ret;
    23. }
    24. };

    6.找到字符串中所有字母异位词

    找到字符串中所有字母异位词

    1. class Solution {
    2. public:
    3. vector<int> findAnagrams(string s, string p) {
    4. int hash1[26] = { 0 };//记录p中的字符出现个数
    5. for(char ch : p) hash1[ch - 'a']++;
    6. int hash2[26] = { 0 };//记录窗口内的字符出现个数
    7. int m = p.size();
    8. vector<int> ret;
    9. for(int left = 0, right = 0, cnt = 0; right < s.size(); right++)
    10. {
    11. char in = s[right];//进窗口
    12. if(++hash2[in - 'a'] <= hash1[in - 'a']) cnt++;//cnt用来记录窗口中出现有效字符的个数
    13. while(right - left + 1 > m) //判断
    14. {
    15. //出窗口
    16. char out = s[left++];
    17. if(hash2[out - 'a']-- <= hash1[out - 'a']) cnt--;
    18. }
    19. if(cnt == m)
    20. ret.push_back(left);//更新结果
    21. }
    22. return ret;
    23. }
    24. };

    7.串联所有单词的子串

    串联所有单词的子串

    1. class Solution {
    2. public:
    3. vector<int> findSubstring(string s, vector& words) {
    4. vector<int> ret;
    5. unordered_mapint> hash1;//记录word字符串数组中有效字符串的个数
    6. for(auto s : words) hash1[s]++;
    7. unordered_mapint> hash2;//记录窗口中有效字符串的个数
    8. int len = words[0].size(), n = words.size();
    9. for(int i = 0; i < len; i++)//执行len次滑动窗口
    10. {
    11. for(int left = i, right = i, cnt = 0; right + len <= s.size(); right += len)
    12. {
    13. string in = s.substr(right, len);
    14. if(++hash2[in] <= hash1[in]) cnt++;//进窗口,cnt记录窗口内有效字符串的个数
    15. while(right - left + 1 > n * len) //判断
    16. {
    17. string out = s.substr(left, len);
    18. if(hash2[out]-- <= hash1[out]) cnt--;//出窗口
    19. left += len;
    20. }
    21. //更新结果
    22. if(cnt == n)
    23. ret.push_back(left);
    24. }
    25. }
    26. return ret;
    27. }
    28. };

     

    8.最小覆盖子串

    最小覆盖子串

    1. class Solution {
    2. public:
    3. string minWindow(string s, string t) {
    4. int hash1[128] = { 0 };//记录t中每个字符的频次
    5. int kinds = 0;//记录t中有效字符的种类
    6. for(char ch : t) if(hash1[ch]++ == 0) kinds++;
    7. int hash2[128] = { 0 };//记录窗口中每个字符出现的频次
    8. int minlen = INT_MAX, begin = -1;
    9. for(int left = 0, right = 0, cnt = 0; right < s.size(); right++)
    10. {
    11. //进窗口
    12. char in = s[right];
    13. if(++hash2[in] == hash1[in]) cnt++;//cnt用来记录窗口内有效字符的种类
    14. while(cnt == kinds)//判断是否符合条件
    15. {
    16. //更新结果
    17. if(right - left + 1 < minlen)
    18. {
    19. minlen = right - left + 1;
    20. begin = left;
    21. }
    22. char out = s[left++];
    23. if(hash2[out]-- == hash1[out]) cnt--;//出窗口
    24. }
    25. }
    26. if(begin == -1) return "";
    27. else return s.substr(begin, minlen);
    28. }
    29. };

     

  • 相关阅读:
    数据库学习
    二叉树的重要概念
    Mongodb操作GridFS案例
    解密Prompt系列4. 升级Instruction Tuning:Flan/T0/InstructGPT/TKInstruct
    vue中用xlsx、xlsx-style、file-saver插件实现用表格原始数据打印excel文件
    使用Unity的Input.GetAxis(““)控制物体移动、旋转
    JavaEE - CORS跨域
    java83-常用基础类object
    机器学习集成学习进阶Xgboost算法原理
    萤火虫优化算法(FA)附matlab代码
  • 原文地址:https://blog.csdn.net/2301_78611726/article/details/138129980