我的课程:滑动窗口问题(c++)

滑动窗口问题要点:

  • 方法一:使用高效容器快速维护元素离开窗口和加入窗口后的信息(映射表、平衡树、单调队列等)
  • 方法二:分段和分块处理

滑动窗口是一种在算法中常用的技巧,主要用来处理具有连续性的子数组或子序列问题。通过滑动窗口,可以在一维数组或字符串上维护一个固定或可变长度的窗口,逐步移动窗口,避免重复计算,从而提升效率。常用于求解子数组的最大/最小值、满足条件的子数组个数等问题。

 算法框架


以下是滑动窗口算法的通用框架:
 滑动窗口算法框架 

void slidingWindow(string s, string t) {
    unordered_map<char, int> need, window;
    for (char c : t) need[c]++;
    int left = 0, right = 0;
    int valid = 0;
    while (right < s.size()) {
        // c 是将移入窗口的字符
        char c = s[right];
        // 右移窗口
        right++;
        // 进行窗口内数据的一系列更新
        ...
        /*** debug 输出的位置 ***/
        printf("window: [%d, %d)\n", left, right);
        /********************/
        // 判断左侧窗口是否要收缩
        while (window needs shrink) {
            // d 是将移出窗口的字符
            char d = s[left];
            // 左移窗口
            left++;
            // 进行窗口内数据的一系列更新
            ...
        }
    }
}


在这个框架中,`right` 指针用于扩展窗口,`left` 指针用于收缩窗口。通过不断地移动这两个指针,可以遍历数组或字符串的所有可能子数组或子字符串。

### 示例代码
下面是一个具体的例子,用于计算数组中长度为 `k` 且平均值大于等于 `threshold` 的子数组的个数:

class Solution {
public:
    int numOfSubarrays(vector<int>& arr, int k, int threshold) {
        int ans = 0;
        int s = 0; // 维护窗口元素和
        for (int i = 0; i < arr.size(); i++) {
            // 1. 进入窗口
            s += arr[i];
            if (i < k - 1) { // 窗口大小不足 k
                continue;
            }
            // 2. 更新答案
            ans += s >= k * threshold;
            // 3. 离开窗口
            s -= arr[i - k + 1];
        }
        return ans;
    }
};


在这个例子中,通过维护一个固定长度为 `k` 的窗口,不断地移动窗口,计算窗口内元素的和,并判断平均值是否大于等于 `threshold`,从而统计满足条件的子数组的个数。

 输入输出要求


以【2024年华为OD机试】 (C卷,100分)- 滑动窗口最大和为例,其输入输出要求如下:
- 第一行输入一个正整数 `N`,表示整数个数(`0 < N < 100000`)。
- 第二行输入 `N` 个整数,整数的取值范围为 `[-100, 100]`。
- 第三行输入一个正整数 `M`,`M` 代表窗口的大小,`M <= 100000`,且 `M <= N`。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值