长度最小的满足和的子数组
原题在这里:
概述题意:
给定数组中,求满足和>=target的子数组的最小数组长度。
1.暴力是不可能暴力的,再怎么说都是维护dp[i]=nums[i,r]
class Solution { public: int minSubArrayLen(int target, vector<int> &nums) { int l = nums.size(), r = 0, ans = l * 2; vector<int> dp(l, 0); // dp[i]=nums[i,r-1] for (int i = 0; i < l; ++i) { if (i != 0) dp[i] = dp[i - 1] - nums[i - 1]; while (dp[i] < target) { if (r == l) break; dp[i] += nums[r++]; } while (dp[i] - nums[r - 1] >= target) dp[i] -= nums[--r]; if (dp[i] >= target) ans = min(ans, r - i); } return ans == l * 2 ? 0 : ans; } };
2.前缀和+二分搜索
逻辑很简单,但是巧妙在于二分搜索的运用:
code:
class Solution { public: int minSubArrayLen(int target, vector<int> &nums) { int l = nums.size(), r = 0, ans = l * 2; vector<int> sum(l + 1, 0); for (int i = 1; i <= l; ++i) sum[i] = sum[i - 1] + nums[i - 1]; for (int i = 1; i <= l; ++i) { int x = target + sum[i - 1]; //找第一个大于等于x的值 auto id = lower_bound(sum.begin(), sum.end(), x); if (id != sum.end()) ans = min(ans, (int)(id - sum.begin() - i + 1)); } return ans == l * 2 ? 0 : ans; } };
3.滑动窗口,同方法一,时间复杂度也是线性的,优于空间复杂度:
code:
class Solution { public: int minSubArrayLen(int target, vector<int> &nums) { int n = nums.size(), l = 0, r = 0, ans = n * 2; int sum = 0; while (r < n) { sum += nums[r]; while (sum >= target) { ans = min(ans, r - l + 1); sum -= nums[l++]; } ++r; } return ans == n * 2 ? 0 : ans; } };
【Over】

浙公网安备 33010602011771号