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。

posted @ 2021-12-28 21:46  太极者  阅读(26)  评论(0编辑  收藏  举报