滑动窗口-长度最小的子数组

长度最小的子数组

滑动窗口-长度最小的子数组

  1. 暴力法: 区间由left, 和right确定, 因此需要两层for循环遍历left和right, O(n^2)
  2. 滑动窗口法: 滑动窗口也是使用双指针确定窗口的left和right, left和right如何移动?, right要从0 到length - 1移动, 步长1, 也就是用for循环, left, 移动取决于sum >= target 使用while动态移动。

题解

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //滑动窗口法: 使用首尾指针控制滑动窗口的起点终点位置。-> 遍历一遍滑动窗口的末尾位置, 动态改变窗口起点 O(n)
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            //使用while使得left可以一直增加刚好sum>=target √
            while (sum >= target) {
                result = Math.min(result, right - left + 1);
                //起点位置向前移动1,保留后面sum计算结果
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

class Solution2 {
    public int minSubArrayLen(int target, int[] nums) {
        // 暴力法: 一层循环遍历元素作为起点, 另一层循环从起点搜索找到合适终点  -> 有重复计算O(nlogn)
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            int sum = 0;
            for (int j = i; j < nums.length; j++) {
                sum += nums[j];
                if (sum >= target) {
                    int subLength = j - i + 1;
                    result = Math.min(subLength, result);
                    break;
                }
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}
posted @ 2022-02-13 13:35  -Rocky-  阅读(37)  评论(0编辑  收藏  举报