题目简介:
给你一个整数数组 nums
和一个整数 k
,找出 nums
中和至少为 k
的 最短非空子数组 ,并返回该子数组的长度。如果不存在这样的 子数组 ,返回 -1
。
子数组 是数组中 连续 的一部分。
示例 1:
1 | 输入:nums = [1], k = 1 |
示例 2:
1 | 输入:nums = [1,2], k = 4 |
示例 3:
1 | 输入:nums = [2,-1,2], k = 3 |
提示:
1 <= nums.length <= 10^5
-10^5 <= nums[i] <= 10^5
1 <= k <= 10^9
思路:
首先计算出每个元素的前缀和并保存下来。
我们可以考虑以下两种情况:
dp[i] - dp[j] >= k
,此时无论i
后面的元素z
是什么,z - j
的长度必定大于i - j
,因此我们就不需要j
了,将其删除。dp[i] <= dp[j]
,此时无论i
后面的元素z
是什么,dp[z] - dp[i]
必定大于等于dp[z] - dp[j]
,因此我们也不需要j
了,将其删除。
通过第二种情况的优化,我们可以发现dp[i]
会形成一个递增序列。
所以当我们优化第一种情况时,可以从前面开始删除(dp[j]
逐渐增大);
优化第二种情况时,便从后面开始删除(dp[j]
逐渐变小),直到dp[j] < dp[i]
时停止;
- 注意遍历到
dp[i]
时,无论是从后面还是从前面开始删除,删除的元素j
都是小于i
的(即j
在i
的前面)。
因此我们需要一个可以从两端删除元素的数据结构,所以我们使用双端队列deque
。
代码如下:
1 | class Solution { |