/**
* 暴力解法
* @param target
* @param nums
*
* target = 7, nums = [2,3,1,2,4,3]
*
* left = 0 , 记录连续数组的起始位置
* sum = 0 , 记录连续数组元素和
* length = Integer.MAX_VALUE 与后续的length取小值
*
* num.length = 6
* right = 0 ,连续数组的结束位置,right < 6;
* sum += nums[0] = 2 < target
* right = 1
* sum += nums[1] = 2 + 3 = 5 < target;
* right = 2
* sum += nums[2] = 2 + 3 + 1 = 6 < target;
* right = 3
* sum += nums[3] = 2 + 3 + 1 + 2 = 8 > target;
* length = min(length , right - left + 1) //right - left + 1 就是连续数组的长度
* 将sum 置为 0 ,重新开始计算
* 连续数组的起始位置 + 1, 此时从nums[1]开始累加
* 连续数组的结束位置也要重置从1开始计算, 因此此时要把right = left - 1 = 0, 由于在循环条件中,下一轮right 会+1;
* 因此此时right = 0, 下一次循环right就是从1开始计数
*如此重复遍历即可
* @return
*/
public static int minSubArrayLen(int target, int[] nums) {
int left = 0 ;
int sum = 0;
int length = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
if (sum >=target){
length = Math.min(length , right - left +1);
sum = 0 ;
left ++ ;
right = left - 1;
}
}
return length == Integer.MAX_VALUE ? 0 : length;
}
/**
* 优化方法
* @param target
* @param nums
* @return
*
* target = 7, nums = [2,3,1,2,4,3]
* left = 0 ,连续数组起始位置,
* sum = 0 ,连续数组和
* length = Integer.MAX_VALUE, 设置为最大值, 与length相比, 取小值
*
* right = 0 ; right < 6 ; right ++
* right = 0 ; sum += nums[0] = 2;
* right = 1 ; sum += nums[1] = 5;
* right = 2 ; sum += nums[2] = 6;
* right = 3 ;
* sum += nums[3] = 8 > target; 注意此时sum > target , 并没有将right 重置, 而是将left + 1;
* length = 4;
* sum -= nums[0] = 6
* left += 1;
* 如此循环
*/
public static int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0 ;
int length = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target){
length = Math.min(length, right - left + 1);
sum -= nums[left];
left ++;
}
}
return length == Integer.MAX_VALUE ? 0 : length;
}
209. 长度最小的子数组
于 2023-10-17 20:59:39 首次发布