leedcode 算法学习记录 数组 滑动窗口

public class HuaDongChuangKou {
    //209 长度最小子串 简单
    //给定一个含有n个正整数的数组和一个正整数 target 。
    //找出该数组中满足其和 ≥ target 的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
    //思路点拨 : 计算长度最小子串时并不需要保持窗口在最小子串 因为只需要记录最小子串长度,所以保证滑动窗口遍历完数组即可
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int sum = 0;
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            while (sum >= target) {
                res = Math.min(res, i - left + 1);
                sum -= nums[left++];
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }

    //904. 水果成篮 中等
    //你正在探访一家农场,,场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
    //你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
    //你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
    //你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
    //一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
    //给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目
    //思路:本题作为一个典型的滑动窗口题目,难点在对于慢指针的处理上,如果遇到第三种数字,要从新计算篮子的空间,与前一题目不同的是慢指针无法从左边开始遍历去排除一种数,因为无法却定要排除那种数以及是否已经找到该数最后一次出现的位置,
    //      我们可以换个思路,既然重签面遍历不成,就从后面遍历,这样的话就可以直接寻找从后往前第二个元素出现位置即可
    public int totalFruit(int[] fruits) {
        int res = 0;//
        int left = 0;
        int n1 = fruits[left];//篮子一号
        int n2 = fruits[0];//篮子二号
        for (int i = 0; i < fruits.length; i++) {//依次遍历快指针  如果数组为空 则直接退出返回结果0
            if (fruits[i] == n1 || fruits[i] == n2) {//如果数字与篮子里的相同
                res = Math.max(res, i - left + 1);//更新最长连续长度
                continue;//进行下一次遍历,快指针移动
            }//如果查询到的该数字不同于俩个篮子里的数  注意有个例外情况 就是刚开始时俩个篮子里放着相同的数字
            left = i - 1;//将慢指针放到快指针前一位  注意因为走到这一步快指针最少也前进了一位,所以慢指针并不会发生数组越位
            n1 = fruits[i];//更新俩个篮子,因为找到新的数字后,应该保留的数字应该是新数字前面的一个,但是可能会缩短窗口长度,所以要向前寻找该数字最靠前的位置
            n2 = fruits[i - 1];//
            while (left >= 1 && fruits[left - 1] == n2) {//为了防止数组越位,left >= 1 一定要放在最前面,否则在第二次循环时变回报错,
                left--;
            }
            res = Math.max(res, i - left + 1);//更新结果
        }
        return res;
    }

    //76. 最小覆盖子串 困难
    //给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。



    public static void main(String[] args) {
        int[] nums = {1, 2, 1};
        HuaDongChuangKou a = new HuaDongChuangKou();
        a.totalFruit(nums);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值