Subarray Sum 2

TAG : subarray + binary_search

[1, 2, 3, 4] [1, 3]

给出一个所有数为正数的数组,还有一个区间,找出在这个区间内可能的子数组的个数

[0, 0] [0, 1] [1, 1] [2, 2]

提示:

prefixsum数组肯定是递增的。对于当前的prefix[j], 使用二分法找出

sum[i][j] = prefix[j] - prefix[i-1];

对于prefix[1]来说,当前的prefix数组是[0, 1]

left < prefix[j] - prefix[i-1] < right

prefix[i-1] < 3-1 = 2

prefix[i-1] > 3-3 = 0

0 < prefix[i-1] < 2

prefix数组为[0, 1] 所以是全部 2个

code

class Solution {
public:
    /**
     * @param A an integer array
     * @param start an integer
     * @param end an integer
     * @return the number of possible answer
     */
    int subarraySumII(vector<int>& A, int start, int end) {
        // Write your code here
        int ret = 0;
        int n = A.size();
        if(n == 0)
        {
            return 0;
        }

        vector<int> prefix;
        prefix.push_back(0);
        int sum = 0;
        for(int i = 1; i <= n; i++)
        {
            sum += A[i-1];

            int left = sum - end;
            int right = sum - start;
            int range = binarysearch(prefix, left, right);
            //cout<<sum<<" "<<left<<" "<<right<<" "<<range<<endl;
            ret += range;

            prefix.push_back(sum);
        }
        return ret;
    }

    int binarysearch(vector<int>& A, int left, int right)
    {
        // find the first element >= left;
        // find the last element <= right;

        if(left > right || A.front() > right || A.back() < left)
        {
            return 0;
        }

        int left_index = 0;
        int right_index = A.size()-1;

        int s = 0;
        int e = A.size()-1;


        while(s + 1 < e)
        {
            int mid = (s+e)/2;
            if(A[mid] >= left)
            {
                e = mid;
            }
            else
            {
                s = mid;
            }
        }

        if(A[e] >= left)
        {
            left_index = e;
        }
        if(A[s] >= left)
        {
            left_index = s;
        }

        // right index

        s = 0;
        e = A.size()-1;

        while(s + 1 < e)
        {
            int mid = (s+e)/2;
            if(A[mid] <= right)
            {
                s = mid;
            }
            else
            {
                e = mid;
            }
        }

        if(A[s] <= right)
        {
            right_index = s;
        }
        if(A[e] <= right)
        {
            right_index = e;
        }

        return right_index-left_index+1;

    }


};

results matching ""

    No results matching ""