【leetcode】滑动窗口题目总结

滑动窗口算法是在给定特定窗口大小(当然也可以是动态可变窗口)的数组或者字符串上进行操作的算法,该算法主要的用途就是在于将嵌套循环时间复杂度的效率优化成为线性时间复杂度。简而言之,滑动窗口算法在一个特定大小的字符串或数组上进行操作,而不在整个字符串和数组上操作,这样就降低了问题的复杂度,从而也达到降低了循环的嵌套深度。

从字面意思上理解的话:

滑动: 说明这个窗口是移动的,也就是移动是按照一定方向来的。

窗口: 窗口大小并不是固定的,可以不断扩容直到满足一定的条件;也可以不断缩小,直到找到一个满足条件的最小窗口;当然也可以是固定大小。

一般来讲,滑动窗口算法需要借助两个指针left与right来完

/* 滑动窗口算法框架 */
void slidingWindow(string s) {
    // 用合适的数据结构记录窗口中的数据,根据具体场景变通
    // 比如说,我想记录窗口中元素出现的次数,就用 map
    // 我想记录窗口中的元素和,就用 int
    unordered_map<char, int> window;
    
    int left = 0, right = 0;
    while (right < s.size()) {
        // c 是将移入窗口的字符
        char c = s[right];
        window.add(c)
        // 增大窗口
        right++;
        // 进行窗口内数据的一系列更新
        ...

        /*** debug 输出的位置 ***/
        // 注意在最终的解法代码中不要 print
        // 因为 IO 操作很耗时,可能导致超时
        printf("window: [%d, %d)\n", left, right);
        /********************/
        
        // 判断左侧窗口是否要收缩
        while (left < right && window needs shrink) {
            // d 是将移出窗口的字符
            char d = s[left];
            window.remove(d)
            // 缩小窗口
            left++;
            // 进行窗口内数据的一系列更新
            ...
        }
    }
}


76. 最小覆盖子串

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char, int> need, window;
        for (auto c : t) {
            need[c]++;
        }

        int left = 0, right = 0;
        int valid = 0;
        int start = 0, len = INT_MAX;

        while (right < s.size()) {
            // 扩大窗口
            char c = s[right];
            right++;

            // 更新满足窗口覆盖需要的相关条件
            if (need.count(c)) {
                window[c]++;
                if (need[c] == window[c]) {
                    valid++;
                }
            }

            // 缩小窗口,并更新覆盖条件
            while (valid == need.size()) {
                // result处理,判断是否更新,便于返回
                if (right - left < len) {
                    start = left;
                    len = right - left;
                }

                // 缩小窗口
                char d = s[left];
                left++;

                if (need.count(d)) {
                    if (need[d] == window[d]) {
                        valid--;
                    }
                    window[d]--;
                }
            }
        }
        return len == INT_MAX ? "" : s.substr(start, len);
    }
};

209. 长度最小的子数组

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0, right = 0;
        int sum = 0;
        int len = INT_MAX;

        while (right < nums.size()) {
            sum += nums[right];
            right++;

            while (sum >= target) {
                if (right - left < len) {
                    len = right - left;
                }

                sum -= nums[left];
                left++;
            }
        }
        return len == INT_MAX ? 0 : len;
    }
};

567. 字符串的排列

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char, int> need, window;
        
        for (auto c : s1) {
            need[c]++;
        }

        int left = 0, right = 0;
        int valid = 0;
        while (right < s2.size()) {
            // 扩大窗口
            char c = s2[right];
            right++;

            // 更新判断条件
            if (need.count(c)) {
                window[c]++;
                if (need[c] == window[c]) {
                    valid++;
                }
            }

            // 缩小窗口时机,固定长度的窗口
            if (right - left == s1.size()) {
                // 有效条件
                if (valid == need.size()) {
                    return true;
                }
                // 缩小窗口
                char d = s2[left];
                left++;

                // 更新判断条件
                if (need.count(d)) {
                    if (need[d] == window[d]) {
                        valid--;
                    }
                    window[d]--;
                }
            }
        }
        return false;
    }
};

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

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<char, int> need, window;
        for (char c : p) need[c]++;

        int left = 0, right = 0, valid = 0;
        vector<int> res;

        while (right < s.size()) {
            char c = s[right];
            right++;

            if (need.count(c)) {
                window[c]++;
                if (window[c] == need[c]) {
                    valid++;
                }
            }

            while (right - left >= p.size()) {
                if (valid == need.size()) {
                    res.push_back(left);
                }

                char d = s[left];
                left++;

                if (need.count(d)) {
                    if (window[d] == need[d]) {
                        valid--;
                    }
                    window[d]--;
                }
            }
        }
        return res;
    }
};

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

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> window;

        int left = 0, right = 0, res = 0;

        while (right < s.size()) {
            char c = s[right];
            right++;

            window[c]++;

            while (window[c] > 1) {
                char d = s[left];
                left++;
                window[d]--;
            }
            res = max(res, right - left);
        }
        return res;
    }
};

相关推荐

  1. leetcode滑动窗口题目总结

    2024-05-04 22:32:01       36 阅读
  2. leetcode滑动窗口问题总结 Python

    2024-05-04 22:32:01       42 阅读
  3. LeetCode——滑动窗口

    2024-05-04 22:32:01       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-04 22:32:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-04 22:32:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-04 22:32:01       82 阅读
  4. Python语言-面向对象

    2024-05-04 22:32:01       91 阅读

热门阅读

  1. 初始MySQL

    2024-05-04 22:32:01       30 阅读
  2. Django框架之模板层

    2024-05-04 22:32:01       23 阅读
  3. leetcode39-Combination Sum

    2024-05-04 22:32:01       33 阅读
  4. 深入浅出 iptables - Linux下的强大防火墙工具

    2024-05-04 22:32:01       37 阅读
  5. 大模型+低代码平台

    2024-05-04 22:32:01       33 阅读
  6. 2024年目标检测数据集大合集所有下载地址汇总

    2024-05-04 22:32:01       169 阅读
  7. SpringBoot camunda

    2024-05-04 22:32:01       30 阅读
  8. 算法:状态压缩dp

    2024-05-04 22:32:01       112 阅读