LeetCode - 862. Shortest Subarray with Sum at Least K

Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K.

If there is no non-empty subarray with sum at least K, return -1.

Example 1:

Input: A = [1], K = 1             Output: 1

Example 2:

Input: A = [1, 2], K = 4         Output: -1

Example 3:

Input: A = [2, 1, 2], K = 3     Output: 3

思路:

    最开始我的思路用一把越来越大的尺子,每次从左往右移,只要有尺子在一个位置上的和大于等于K,那就直接返回当前尺子的长度,而且在计算尺子内的值的和时,可以先算出第一个位置上的和,之后往后移动的时候,每次加上新的值(right),减去旧的值(left - 1)。这样只要答案的长度不是太大,大循环(每次尺子长度+1)就不会循环太多次。

int shortestSubarray(vector<int>& A, int K)
{
    if(A.size() == 1)
        return A[0] >= K ? 1 : 0;
    bool isFind;
    for(int i = 0; i < A.size(); i++)   // 先看看每个数有没有
    {
        if(A[i] >= K)
        return 1;
    }
    for(int len = 1; len < A.size(); len++) // 每次循环用len长度的尺子从左往右走
    {
        int left = 0;
        int right = len;
        int cur_sum = 0;
        for(int t = left; t <= right; t++)
            cur_sum += A[t];
        if(cur_sum >= K)
            return len + 1;
        while(right  < A.size() - 1)
        {
            ++left;
            ++right;
            cur_sum += A[right];
            cur_sum -= A[left - 1];
                
            if(cur_sum >= K)
                return len + 1;
        }
    }
    return -1;
}

    思路以及答案没有问题,但是25万个数的时候,超时了,答案使用deque(有的使用priority_queue)来完成。大致思路是,计算每个位置上,加上后边多少位的数,能够大于等于K,找出最小的。

int shortestSubarray(vector<int> A, int K) 
{
    int N = A.size(), res = N + 1;
    vector<int> B(N + 1, 0);
    for (int i = 0; i < N; i++) B[i + 1] += B[i] + A[i];
    deque<int> d;
    for (int i = 0; i < N + 1; i++)
    {
        while (d.size() > 0 && B[i] - B[d.front()] >= K)
            res = min(res, i - d.front()), d.pop_front();
        while (d.size() > 0 && B[i] <= B[d.back()]) d.pop_back();
            d.push_back(i);
    }
    return res <= N ? res : -1;
}

猜你喜欢

转载自blog.csdn.net/Bob__yuan/article/details/81067324