LeetCode 862 和至少为K的最短子数组[前缀和 双端队列] HERODING的LeetCode之路

Posted HERODING23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 862 和至少为K的最短子数组[前缀和 双端队列] HERODING的LeetCode之路相关的知识,希望对你有一定的参考价值。


解题思路:
从求和再加上数组的长度,很容易联想到以空间换时间的方法——前缀和,由于数组中元素有负数,所以无法通过前缀和的单调性直接判断出结果,所以我们定义一个队列,用来存储已经访问过的前缀和下标,这些下标表示以该下标开始的序列目前还没找到满足条件的子序列,遍历每个前缀和,和队首进行比较,把所有满足条件的前缀和长度进行更新,并把队首出队列(已经找到满足条件的最短序列就不用留在队列中),同时对于留在队列中的前缀和下标,从队尾开始比较是否比当前前缀和大,大了也直接出队列,这相当于剪枝,因为保证序列最短,最后将当前前缀和放入队列中,代码如下:

class Solution 
public:
    int shortestSubarray(vector<int>& nums, int k) 
        int n = nums.size();
        vector<long> prefix(n + 1, 0);
        for(int i = 1; i <= n; i ++) 
            prefix[i] = prefix[i - 1] + nums[i - 1];
        
        int minLen = INT_MAX;
        deque<int> q;
        for(int i = 0; i <= n; i ++) 
            long curSum = prefix[i];
            // 如果当前位置到队首的和满足k的条件
            while(!q.empty() && curSum - prefix[q.front()] >= k) 
                minLen = min(minLen, i - q.front());
                q.pop_front();
            
            // 把队尾大的前缀和去掉
            while(!q.empty() && curSum <= prefix[q.back()]) 
                q.pop_back();
            
            q.push_back(i);
        
        return minLen == INT_MAX ? -1 : minLen;
    
;

以上是关于LeetCode 862 和至少为K的最短子数组[前缀和 双端队列] HERODING的LeetCode之路的主要内容,如果未能解决你的问题,请参考以下文章

862. 和至少为 K 的最短子数组

LeetCode 862 和至少为K的最短子数组[前缀和 双端队列] HERODING的LeetCode之路

力扣 每日一题 862. 和至少为 K 的最短子数组难度:困难,rating: 2306(前缀和+单调队列)

力扣 每日一题 862. 和至少为 K 的最短子数组难度:困难,rating: 2306(前缀和+单调队列)

862. 和至少为 K 的最短子数组(困难)-前缀和单调双端队列

算法/编程练习:和至少为K的最短子数组