LeetCode 209 Minimum Size Subarray Sum

Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead.

For example, given the array [2, 3, 1, 2, 4, 3] and s = 7, the subarray [4,3] has the minimal length under the problem constraint.

click to show more practice.

More practice:
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).

Diffculty
Medium

Similar Problems

[LeetCode 76] Minimum Window Substring Hard [LeetCode 325] Maximum Size Subarray Sum Equals k Medium

Analysis

思路一 这道题给定了我们一个数字,让我们求子数组之和大于等于给定值的最小长度, 跟之前那道 Maximum Subarray 最大子数组有些类似,并且题目中要求我们实现O(n)和O(nlgn)两种解法, 先来看O(n)的解法,我们需要定义两个指针left和right,分别记录子数组的左右的边界位置,然后我们让right向右移, 直到子数组和大于等于给定值或者right达到数组末尾,此时我们更新最短距离,并且将left像右移一位, 然后再sum中减去移去的值,然后重复上面的步骤,直到right到达末尾,且left到达临界位置, 即要么到达边界,要么再往右移动,和就会小于给定值。

思路二 再来看看O(nlgn)的解法,这个解法要用到二分查找法, 思路是,我们建立一个比原数组长一位的sums数组,其中sums[i]表示A数组中[0, i - 1]的和, 然后我们对于sums中每一个值sums[i],用二分查找法找到子数组的右边界位置, 使该子数组之和大于sums[i] + s,然后我们更新最短长度的距离即可。

Solutions

解法一:O(N)

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& A) {
        if (A.empty()) return 0;
        int n = A.size(), res = n + 1;
        int left = 0, right = 0, sum = 0;
        while (right < n) {
            while (sum < s && right < n) {
                sum += A[right++];
            }
            while (sum >= s) {
                res = min(res, right - left);
                sum -= A[left++];
            }
        }
        return res == n + 1 ? 0 : res;
    }
};

解法二:O(NlogN)

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& A) {
        int len = A.size(), sums[len + 1] = {0}, res = len + 1;
        for (int i = 1; i < len + 1; ++i) sums[i] = sums[i - 1] + A[i - 1];
        for (int i = 0; i < len + 1; ++i) {
            int right = searchRight(i + 1, len, sums[i] + s, sums);
            if (right == len + 1) break;
            res = min(res, right - i);
        }
        return res == len + 1 ? 0 : res;
    }
    int searchRight(int left, int right, int key, int sums[]) {
        while (left <= right) {
            int mid = (left + right) / 2;
            if (sums[mid] >= key) right = mid - 1;
            else left = mid + 1;
        }
        return left;
    }
};
Reference

results matching ""

    No results matching ""