209. 长度最小的子数组

307 阅读1分钟

思路:滑动窗口

  • i j 初始化到index = 0处,sum = 0。
  • 循环执行:
    • j向右滑动到sum满足条件,记录length。
    • i向左滑动到sum不满足条件。 核心代码先写
while (j < nums.length) {
    sum += nums[j];
    //插入:sum满足>=target的条件后,左端缩小
    j++;
}

然后才想到在这两句话中间插入i++,使得窗口变小

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int res = Integer.MAX_VALUE;
        int i = 0, j = 0;
        int sum = 0;
        while (j < nums.length) {
            //窗口右端点向右滑动
            while (j < nums.length && sum < target) {
                sum += nums[j];
                j++;
            }
            //开始收缩左端点
            while (sum >= target) {
                res = Math.min(res, j - i);//更新min
                sum -= nums[i];
                i++;
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}

简化

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int i = 0, j = 0;
        int sum = 0;
        int min = Integer.MAX_VALUE;
        while (j < nums.length) {
            sum += nums[j];//窗口右端点向右滑动
            
            while (sum >= target) {
                min = Math.min(min, j - i + 1);
                sum -= nums[i];
                i++;
            }
            j++;
        }
        return min == Integer.MAX_VALUE ? 0 : min;//min 没变化,说明凑不到target
    }
}