思路:双指针 O(n)
class Solution {
public:
using ll = long long;
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
ll sums = accumulate(nums.begin(), nums.end(), 0ll);
if (sums < target) return 0; //
if (sums == target) return n; //
int l = 0, ans = INT_MAX, sum = 0;
for (int r = 0; r < n; ++r) {
sum += nums[r];
while(sum - nums[l] >= target) sum -= nums[l++];
if (sum >= target) ans = min(ans, r - l + 1); //因为题目是大于,所以这里要加判断
}
return ans;
}
};
易错点:
1:特殊判断,不然最后ans为INT_MAX时 return 0
2:特殊判断
leetcode713. 乘积小于 K 的子数组(中等)
https://blog.csdn.net/zhangjiaji111/article/details/125117140
思路二:二分+前缀和 时间复杂度:O(nlogn)
具体实现:二分区间:[1 , n]
class Solution {
public:
bool judge(vector<int>& sums, int target, int mid) {
if (sums[mid - 1] >= target) return true;
for (int i = mid; i < sums.size(); ++i) {
if (sums[i] - sums[i - mid] >= target) return true;
}
return false;
}
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
vector<int> sums(n);
sums[0] = nums[0];
for (int i = 1; i < n; ++i) sums[i] = nums[i] + sums[i - 1];
int l = 0, r = n + 1;
while (l + 1 < r) {
int mid = l + (r - l) / 2;
if (judge(sums, target, mid)) r = mid;
else l = mid;
}
if (r != (n + 1)) return r;
return 0; //如果不存在符合条件的子数组,返回 0
}
};