问题:
给定一个整型数组和一个数字s,找到数组中最短的一个连续子数组,使得连续子数组的数字和sum>=s,返回这个最短的连续子数组的长度值。
示例:
如,给定数组[2, 3, 1, 2, 4, 3],s = 7。答案为[ 4, 3 ],返回2。
方法一:
暴力法,遍历所有的连续子数组[i…j],计算其和sum,验证sum>=s,时间复杂度O(n^2)。
方法一代码:
package com.haobi;
public class MinSubArrayLen {
public static void main(String[] args) {
// int[] arr = {1,2,4,5,7,8,4,5,6,1,2,5};
int[] arr = {1,5,1,5,1,5,1,5,1,5,1,5};
minSubArrayLen(10, arr);
}
public static void minSubArrayLen(int s, int[] arr) {
int count = 0;
int index = 0;
int minLen = Integer.MAX_VALUE;
for(int i=0;i<arr.length;i++) {
for(int j=i;j<arr.length;j++) {
count += arr[j];
index++;
if(count >= s && index < minLen) {
minLen = index;
count = 0;
index = 0;
continue;
}
}
}
System.out.println(minLen);
}
}
方法二:
双索引技术/滑动窗口
时间复杂度:O(n)
空间复杂度:O(1)
方法二代码:
package com.haobi;
public class MinSubArrayLen1 {
public static void main(String[] args) {
// int[] arr = {1,2,4,5,7,8,4,5,6,1,2,5};
int[] arr = {1,5,1,5,1,5,1,5,1,5,1,5};
System.out.println(minSubArrayLen(10, arr));
}
public static int minSubArrayLen(int s, int[] nums) {
int l = 0,r = -1;//nums[l...r]为我们的滑动窗口
int sum = 0;
int res = nums.length + 1;//初始化
while(l < nums.length) {
if(sum < s && r+1 < nums.length) {
sum += nums[++r];
}else {
sum -= nums[l++];
}
if(sum >= s) {
if(res > r-l+1) {
return r-l+1;
}else {
return res;
}
}
}
if(res == nums.length+1)
return 0;
return res;
}
}