滑动窗口——双指针

滑动窗口法可以用来解决一些查找满足一定条件的连续区间的性质(长度等)问题,可以看做是一种双指针方法的特例,两个指针都起始于原点,并一前一后向终点前进。还有一种双指针方法,其两个指针一始一终,并相向靠近,这种方法的内在思想和滑动窗口非常类似

1. 爱生气的书店老板

代码实现:

滑动窗口——双指针:一前一后

int maxSatisfied(int *customers, int customersSize, int *grumpy, int grumpySize, int minutes) {
    int sum = 0;
    for (int i = 0; i < customersSize; i++) {
        if (grumpy[i] == 0) {
            sum += customers[i];
        }
    }
    int increase = 0;
    int i = 0, j = minutes - 1;
    while (j < customersSize) {
        int num = 0;
        for (int k = i; k <= j; k++) {
            if (grumpy[k] == 1) {
                num += customers[k];
            }
        }
        if (num > increase) {
            increase = num;
        }
        i++;
        j++;
    }
    return sum + increase;
}

2. 长度最小的子数组

代码实现:

int minSubArrayLen(int target, int *nums, int numsSize) {
    int result = INT32_MAX;
    int sum = 0; // 滑动窗口数值之和
    int i = 0; // 滑动窗口起始位置
    int subLength = 0; // 滑动窗口的长度
    for (int j = 0; j < numsSize; j++) {
        sum += nums[j];
        // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
        while (sum >= target) {
            subLength = (j - i + 1); // 取子序列的长度
            result = result < subLength ? result : subLength;
            sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
        }
    }
    // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
    return result == INT32_MAX ? 0 : result;
}

3. 最小覆盖子串

代码实现:

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

代码实现:

5. 最大连续1的个数 III

代码实现:

6. 盛最多水的容器

代码实现:

方法一:暴力解法——超时

#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))

int maxArea(int *height, int heightSize) {
    int ans = 0;
    for (int i = 0; i < heightSize; i++) {
        for (int j = i; j < heightSize; j++) {
            int area = min(height[i], height[j]) * (j - i);
            ans = max(ans, area);
        }
    }
    return ans;
}

方法二:双指针

#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))

int maxArea(int *height, int heightSize) {
    int l = 0, r = heightSize - 1;
    int ans = 0;
    while (l < r) {
        int area = min(height[l], height[r]) * (r - l);
        ans = max(ans, area);
        if (height[l] <= height[r]) {
            l++;
        } else {
            r--;
        }
    }
    return ans;
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值