LeetCode209 长度最小的子数组
做这个题是为了学习前缀和数组,自己在做这个题的时候,使用的是滑动窗口方法,比前缀和要快。下面记录前缀和的方法,因为在刷这个题的时候,没有用前缀和做出来。
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
class SolutionLeetCode209 { public: int minSubArrayLen(int s, vector<int>& nums) { int n = nums.size(); if (n == 0) { return 0; } int ans = INT_MAX; vector<int> sums(n + 1, 0); // sums[i] 表示nums[0] ~ nums[i -1]的和 for (int i = 0; i < nums.size(); i++) { sums[i + 1] = sums[i] + sums[i]; } for (int i = 1; i <= n; i++) { int target = s + sums[i - 1]; auto bound = lower_bound(sums.begin(), sums.end(), target); if (bound != sums.end()) { ans = min(ans, static_cast<int>((bound - sums.begin()) - (i - 1))); } } return ans == INT_MAX ? 0 : ans; } };
这里重点解释两条语句,因为自己在看的时候很费劲
为什么要求一个target出来?重点理解一个问题:前缀和数组中的两项相减的含义,sums[m] - sums[n] ---> 表示原数组nums[n] ~ nums[m - 1]的和。因此target = s + sum[i - 1],则表示对于前缀和数组中的任一项sums[i]加上目标s后,会到达sums中的一个位置pos,这个位置减去(i - 1),则就是nums[i - 1] ~ nums[pos]的数据的和,则pos - (i - 1)即为nums中两个数的位置。
lower_bound:c++中二分法查找函数,是个模板函数,内部使用二分法在sums中查找到target的位置,位于i ~ i + 1之间,返回i。