长度最小的子数组
滑动窗口-长度最小的子数组
- 暴力法: 区间由left, 和right确定, 因此需要两层for循环遍历left和right, O(n^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;
}
}