题目大意:
给你一个整数数组\(nums\)和一个整数\(k\),找出\(nums\)中和至少为\(k\)的最短非空子数组,并返回该子数组的长度。如果不存在这样的子数组,返回\(-1\)。
子数组是数组中连续的一部分。
题解:
由于数组中可能出现负数,所以尺取法不可行,需要使用单调队列维护前缀和。
使用单调队列的正确性证明
class Solution {
public:
int shortestSubarray(vector<int>& nums, int k) {
if (nums.empty()) {
return -1;
}
int n = nums.size();
std::vector<long long> sum(n + 1);
for (int i = 1; i <= n; ++i) {
sum[i] = sum[i - 1] + nums[i - 1];
}
int ans = n + 1;
std::deque<int> deq;
for (int i = 0; i <= n; ++i) {
while (!deq.empty() && sum[i] <= sum[deq.back()]) {
deq.pop_back();
}
while (!deq.empty() && sum[i] - sum[deq.front()] >= k) {
ans = std::min(ans, i - deq.front());
deq.pop_front();
}
deq.push_back(i);
}
return ans == n + 1 ? -1 : ans;
}
};