题目要求出一个仅包含正数的数组nums中最小的子数组(连续)使得子数组中所有元素的和大于一个给定的数s,并返回该子数组的长度。
题目来源: Minimum Size Subarray Sum
解法一:暴力搜索 O(n^2)
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int min = INT_MAX;
for(int i = 0; i < nums.size(); i++) {
int sum = 0;
for(int j = i; j < nums.size(); j++) {
sum += nums[i];
if(sum >= s && i - j + 1 < min) {
min = i - j + 1;
continue;
}
}
}
return min == INT_MAX ? 0 : min;
}
};
解法二:Two Pointer O(n)
看了tags以后,想起来这类问题其实包含了很多重复的子问题,暴力搜索往往太过浪费。我们实际上是想要一个最小窗,这个窗可以通过左右两个指针start和end进行模拟。由于所有元素都是正数,我们只要先确定窗口的右边界,再逐渐缩从左边界进行压缩即可。
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int sum = 0, start = 0, minlen = INT_MAX;
bool flag = false;
for(int end = 0; end < nums.size(); i++) {
sum += nums[end];
if(sum >= s) {
flag = true;
while(sum >= s)
sum -= nums[start++];
if(minlen > i - start + 2)
minlen = i - start + 2;
}
}
if(flag)
return minlen;
else
return 0;
}
};