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.


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).

解答:

1.O(n)  two points

用begins指针记录子串开头的位置,每次遍历一个字符,判断sum是否大于s,若是,则将该sum记录minlen中(sum<minlen);然后将begins+1,并将nums[begin]元素减去;若sum小于s,则 i+1, 且将其值加入sum中。以下为我的代码:

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int begins = 0;
        int len = nums.size();
        if(len == 0)
            return 0;
        if(len==1){
            if(nums[0]==s)
            return 1;
            else
            return 0;
        }
        int minlen = len+1;
        int sum = nums[0];
        int i = 0;
        while(i < len){
            if(sum >= s){
                int l = i - begins+1;
                if(l < minlen)
                    minlen = l;
                sum = sum-nums[begins];
                ++begins;
            }else{
                    if(i+1>=len)
                        break;
                    sum = sum+nums[++i];
            }
        }
        if(minlen == len+1)
            return 0;
        else
            return minlen; 
    }
};

别人优秀的代码:(思路差不多)

O(n)

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int n = nums.size(), start = 0, sum = 0, minlen = INT_MAX;
        for (int i = 0; i < n; i++) { 
            sum += nums[i]; 
            while (sum >= s) {
                minlen = min(minlen, i - start + 1);
                sum -= nums[start++];
            }
        }
        return minlen == INT_MAX ? 0 : minlen;
    }
};



2.O(nlogn) 

对于要求该复杂度,就要想到二分查找的方法。但是二分查找是对递增序列的,而原序列无法进行更改顺序,因此怎么找递增序列呢? 那就找从开头到每个元素的和的序列。如:  nums=[2,3,1,2,4,3]序列,则sums=[0,2,5,6,8,12,15].然后对于每个元素sums[i],找sums数组中大于sums[i]+s的值,用二分查找。找到后的位置j-i就是要求的长度。

这里调用别人的优秀的代码:

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int len = nums.size(), sums[len + 1] = {0}, res = len + 1;
        for (int i = 1; i < len + 1; ++i) sums[i] = sums[i - 1] + nums[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;
            if (res > right - i) 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;
    }
};



你可能感兴趣的:(LeetCode,C++,substring,point,Two)