在这里插入图片描述

长度最小的子数组

力扣题目网址:

  1. 长度最小的子数组
    给定一个含有 n 个正整数的数组和一个正整数 target 。
    找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

在这里插入图片描述

这个题目我们可以以最左边的数为起点开始枚举,依次向右扩展,每次加新枚举的数,但是加完之后我们先不用老老实实的尽行继续扩展,而是我们可以保留此次计算出来的数的和删除最左边的那个数是否大于等于目标值,直到小于目标值为止,这样我们就可以精确的计算出最小的那个数组,然后每一次枚举中比较数组长度的最小值,比较完之后就可以获取的最小长度。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int ans = n + 1;
        int left = 0;
        int s = 0;
        for (int right = 0; right < n; right++) {
            s += nums[right];
            while (s - nums[left] >= target) {
                s -= nums[left];
                left += 1;
            }
            if(s >= target){
                ans = Math.min(ans, right - left + 1);
            }
        }
        return ans <= n ? ans : 0;
    }
}

乘积小于 K 的子数组

力扣题目网址:

  1. 长度最小的子数组
    给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。

示例 1:
输入:nums = [10,5,2,6], k = 100
输出:8
解释:8 个乘积小于 100 的子数组分别为:[10]、[5]、[2]、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。
需要注意的是 [10,5,2] 并不是乘积小于 100 的子数组。

我们运用上题滑块思想同理也可以做这道题

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        if(k<= 1) return 0;
        int n = nums.length;
        int v = 1;
        int res = 0;
        int left = 0;
        for(int right = 0; right < n; right++) {
            v *= nums[right];
            while(v >= k){
                v /= nums[left];
                left++;
            }
            res += right - left + 1;
        }
        return res;
    }
}

更多推荐