862. 和至少为 K 的最短子数组
Posted 不吐西瓜籽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了862. 和至少为 K 的最短子数组相关的知识,希望对你有一定的参考价值。
算法记录
LeetCode 题目:
返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。
说明
一、题目
如果没有和至少为 K 的非空子数组,返回 -1 。
二、分析
- 首先看测试的样例数据就知道暴力肯定会超时, 那就只能观察一下题目的规则来寻求比较优质的解法了.
- 题意寻找的是一段连续区间之和, 而且区间之和需要大于一个数值, 说到区间之和的求解, 我们就可以先把前序和给算出来备用.
i
和j
前序和的差值也就意味着区间 i~j 的和, 这样的话就好办了, 只需要遍历整个前序和, 找出距离最小的满足条件的区间不就可以了么, 但是这样也会进行暴力, 有没有好一点的解法呢?- 再看如果我们已经拿到了一个区间满足条件, 我们继续找其他的区间和判断是否还有优于这个解的, 如果
j
继续往后走, 区间距离是不是就增大了, 肯定不是优解, 如果i
往后走, 找到一个比当前的点还要小的值, 也就是同样满足条件而且距离还更小, 就会更新最优. - 分析过后会发现每次寻找的更新解是一个不增的序列, 也就可以用一个单调队列来进行状态的额保存.
class Solution {
public int shortestSubarray(int[] nums, int k) {
long[] sum = new long[nums.length + 1];
for (int i = 1; i <= nums.length; i++) sum[i] = sum[i - 1] + nums[i - 1];
Deque<Integer> queue = new LinkedList<>();
int minLength = sum.length;
for (int i = 0; i < sum.length; i++) {
while (!queue.isEmpty() && sum[queue.peekLast()] >= sum[i]) queue.pollLast();
while (!queue.isEmpty() && sum[i] - sum[queue.peekFirst()] >= k) {
minLength = Math.min(minLength, i - queue.pollFirst());
}
queue.addLast(i);
}
if (minLength == sum.length) return -1;
else return minLength;
}
}
总结
熟悉前缀和方法和单调队列的使用。
以上是关于862. 和至少为 K 的最短子数组的主要内容,如果未能解决你的问题,请参考以下文章
⭐算法入门⭐《队列 - 单调队列》困难03 —— LeetCode 862. 和至少为 K 的最短子数组
862. 和至少为 K 的最短子数组(困难)-前缀和单调双端队列
力扣 每日一题 862. 和至少为 K 的最短子数组难度:困难,rating: 2306(前缀和+单调队列)
力扣 每日一题 862. 和至少为 K 的最短子数组难度:困难,rating: 2306(前缀和+单调队列)