209. 长度最小的子数组
我的代码:错误的滑动窗口
public int minSubArrayLen(int target, int[] nums) {
int left = 0, right = 0;
int sum = nums[0];
int count = 10000;
for (int i = 1; i < nums.length; i++) {
sum += nums[i];
}
if (sum < target) return 0;
sum = nums[0];
while (true) {
if (right < nums.length - 1 && sum < target) {
right++;
sum += nums[right];
}
else if (left < nums.length - 1 && sum >= target) {
count = Math.min(count, right - left + 1);
sum -= nums[left];
left++;
} else {
break;
}
}
return count;
}
暴力
public int minSubArrayLen(int target, int[] nums) {
// 暴力
int sum = 0, count = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
sum = 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
if (sum >= target) {
count = Math.min(count, j - i + 1);
break;
}
}
}
return count == Integer.MAX_VALUE? 0:count;
}
正确的滑动窗口
public int minSubArrayLen(int s, int[] nums) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= s) {
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
思考:
- 学会了 return 时的特殊情况判断
- 退出循环的条件要找到
- 基本思路:不断扩大区间(right++),如果sum >= target,就缩小区间(left++)。即外层循环不断扩大区间,内层循环判断是否缩小区间。