LC209.长度最小的子数组
思路1:滑动窗口
此题可以当做滑动窗口的模板题,非常典型,希望熟读他人代码,清楚滑动窗口的一般逻辑。
代码1:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0, right = 0;
int n = nums.size();
int cur_sum = 0;
int min_len = 0x3f3f3f3f;
while (right < n) {
cur_sum += nums[right];
while (cur_sum >= target) {
cur_sum -= nums[left];
min_len = min(min_len, right - left + 1);
left += 1;
}
right += 1;
}
return min_len == 0x3f3f3f3f ? 0 : min_len;
}
};
思路2:二分查找
变成前缀和
summ
- 对于下标为
x
的summ[x]
而言,其右边一定有一个数summ[y]
,满足summ[y]
是summ[y] - summ[x] >= target
的第一个数,那么子数组长度就是y - x
-
代码2:
class Solution { public: int findLen(vector<long long>& summ, int begin_pos, int target) { int n = summ.size(); int left = begin_pos, right = n - 1; while (left < right) { int mid = (left + right) / 2; if (summ[mid] - summ[begin_pos] >= target) { right = mid; } else { left = mid + 1; } } if (summ[left] - summ[begin_pos] >= target) { return left - begin_pos; } else { return -1; } } int minSubArrayLen(int target, vector<int>& nums) { int n = nums.size(); vector<long long> summ(n + 1, 0); for (int i = 1; i <= n; i++) { summ[i] = summ[i - 1] + nums[i - 1]; } int min_len = 0x3f3f3f3f; for (int i = 0; i < n; i++) { int fit_len = findLen(summ, i, target); if (fit_len == -1) { continue; } min_len = min(min_len, fit_len); } return min_len == 0x3f3f3f3f ? 0 : min_len; } };