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

算法记录

LeetCode 题目:

  返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。



说明

一、题目

  如果没有和至少为 K 的非空子数组,返回 -1 。

二、分析

  • 首先看测试的样例数据就知道暴力肯定会超时, 那就只能观察一下题目的规则来寻求比较优质的解法了.
  • 题意寻找的是一段连续区间之和, 而且区间之和需要大于一个数值, 说到区间之和的求解, 我们就可以先把前序和给算出来备用.
  • ij 前序和的差值也就意味着区间 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;
    }
}

总结

熟悉前缀和方法和单调队列的使用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值