滑动窗口类型:

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0

思路:

* 快慢指针变形,滑动窗口理论:就是不断的调节子序列的起始位置和终止位置
* 窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
* 窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。i++
* 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,窗口的起始位置设置为数组的起始位置就可以了。
*
* 最小滑窗模板:给定数组 nums,定义滑窗的左右边界 i, j,求满足某个条件的滑窗的最小长度。
* while j < len(nums):
*     判断[i, j]是否满足条件
*     while 满足条件:
*         不断更新结果(注意在while内更新!)
*         i += 1 (最大程度的压缩i,使得滑窗尽可能的小)
*     j += 1
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int right;
        int sum = 0;//表示窗口内序列的总和
        int result = Integer.MAX_VALUE;//当前环境表示的最大常量
        for (right = left; right < nums.length; right++) {
            sum += nums[right];
            //if改为while原因是必须保证在左指针左移一位的同时若sum总和还是大于目标值时,右指针不能移动,仍然进入该循环
            while (sum >= target) {
                //记录连续子数组的最小长度
                result = ((right - left + 1) < result) ? (right - left + 1) : result;
                sum -= nums[left];
                left++;//左指针左移一位
            }
        }
        return (result == Integer.MAX_VALUE) ? 0 : result;
    }
}

904. 水果成篮

你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

  • 你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
  • 你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
  • 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。

给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。

* 思路:最大滑窗模板:给定数组 nums,定义滑窗的左右边界 i, j,求满足某个条件的滑窗的最大长度。
* while j < len(nums):
* 判断[i, j]是否满足条件
* while 不满足条件:
* i += 1 (最保守的压缩i,一旦满足条件了就退出压缩i的过程,使得滑窗尽可能的大)
* 不断更新结果(注意在while外更新!)
* j += 1
class Solution {
    public int totalFruit(int[] fruits) {
        int[] arr = new int[fruits.length];//代表所有水果种类的数组
        int i = 0, j = 0;
        int result = -1;
        int count = 0; //计算当前已有的水果种类
        while (j < fruits.length) {
            //新增加了一种水果,判断当前是否满足条件
            if (arr[fruits[j]] == 0) {
                count++;
            }
            arr[fruits[j]]++;
            //不满足条件
            while (count > 2) {
                //即将退出的水果元素数量只有1的情况下
                if (arr[fruits[i]] == 1) {
                    count--;
                }
                arr[fruits[i]]--;
                i++;
            }
            //不断更新结果
            result = Math.max(result, (j - i + 1));
            j++;
        }
        return result;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
滑动窗口是一种常用的算法技巧,可以用于解决一类问题,其中包括一些LeetCode上的题目。通过维护一个窗口,我们可以在线性时间内解决一些需要处理连续子数组或子字符串的问题。以下是一些常见的滑动窗口问题: 1. 最小覆盖子串(Minimum Window Substring):给定一个字符串S和一个字符串T,在S中找出包含T所有字符的最小子串。 2. 字符串的排列(Permutation in String):给定两个字符串s1和s2,判断s2是否包含s1的排列。 3. 找到字符串中所有字母异位词(Find All Anagrams in a String):给定一个字符串s和一个非空字符串p,找到s中所有是p的字母异位词的子串。 4. 替换后的最长重复字符(Longest Repeating Character Replacement):给定一个只包含大写英文字母的字符串s,你可以将一个字母替换成任意其他字母,使得包含重复字母的最长子串的长度最大化。 5. 至多包含两个不同字符的最长子串(Longest Substring with At Most Two Distinct Characters):给定一个字符串s,找出至多包含两个不同字符的最长子串的长度。 以上只是几个例子,滑动窗口可以应用于更多类型的问题。在解决这些问题时,我们通常使用两个指针来表示窗口的左右边界,并根据具体问题的要求移动窗口。在每次移动窗口时,我们可以更新窗口的状态,例如统计字符出现次数、判断窗口是否满足条件等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值