暴力法
会超时
管解1:前缀和 + 二分查找
o NlogN
计算前缀和是为了便捷计算i,j之间的元素和(sums[j] - sums[i])
java
class Solution {
public int minSubArrayLen(int target, int[] nums) {
// 前缀和、二分查找
int n = nums.length;
int res = Integer.MAX_VALUE;
// 计算前缀和
int[] sums = new int[n+1];
for(int i=1;i<=n;i++){
sums[i] = sums[i-1] + nums[i-1];
}
// sums[j] - sums[i] >= s
for(int i=1; i<=n; i++){
int j = target + sums[i-1];
int bound = Arrays.binarySearch(sums, j);
// 如果无法找到,返回 -(插入点)-1
if(bound < 0){
bound = - bound - 1;
}
if(bound <= n){
res = Math.min(res, bound - (i - 1) );
}
}
return res == Integer.MAX_VALUE ? 0 : res;
}
}
管解2:滑动窗口
o N
设置一个滑动窗口:
- 首先开始时,start、end都指向第一个元素
- 开始增加end,直到>=target, 满足条件,记录最小结果
- 逐步增加start(缩短窗口),如果满足条件>=target,继续记录比较最小结果。
java
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
if(n == 0) return 0;
int res = Integer.MAX_VALUE;
int start = 0,end = 0;
int sum = 0;
while( end < n){
sum += nums[end];
while(sum >= target){
res = Math.min(res, end - start + 1);
sum -= nums[start];
start++;
}
end++;
}
return res == Integer.MAX_VALUE ? 0 : res;
}
}