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

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

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

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

  • 示例 1:

输入:A = [1], K = 1
输出:1

  • 示例 2:

输入:A = [1,2], K = 4
输出:-1

  • 示例 3:

输入:A = [2,-1,2], K = 3
输出:3

提示:

  • 1 <= A.length <= 50000
  • -10 ^ 5 <= A[i] <= 10 ^ 5
  • 1 <= K <= 10 ^ 9

解题思路

  1. 对于新加入的y,前面的P[x]都要比新加入的P[y]要小,比P[y]大的P[?]都要pop掉,甚至如果都比P[y]大,整个队列都要清空。为什么?

因为对于当前y来说,必须满足P[y]-P[x]>=K,k又必然是正数,所以p[y]必须大于p[x]。对于y后面的y2来说,即使满足P[y2]-P[x]>=K,[x,y2]之间也不是最短的,因为p[y]<p[x],所以必然满足P[y2]-P[y]>=K,y比x更加接近y2,生成的长度更短,所以x可以直接pop掉,对答案不会产生影响

  1. 为什么当队列里第一个x满足P[y]-P[x]>=K的时候,第一个x可以被pop掉?

因为此时我们构成了一个P[y]-P[x]>=K,这个y已经是最接近x的了,即长度最短,后面即使还能满足P[y]-P[x]>=K,长度也不够当前长度短

代码


class Solution {

    public int shortestSubarray(int[] nums, int k) {

        int n=nums.length,res=n+1;

        LinkedList<Integer> list=new LinkedList<>();

        long[] pre=new long[n+1];

        for(int i=1;i<=n;i++)

            pre[i]=pre[i-1]+(long)nums[i-1];

        for(int i=0;i<n+1;i++)

        {

            while(!list.isEmpty()&&pre[i]<pre[list.getLast()])

                list.removeLast();

            while(!list.isEmpty()&&pre[i]-pre[list.getFirst()]>=k)

            {

                res=Math.min(res,i-list.removeFirst());

            }

            list.add(i);

        }

        return res==n+1?-1:res;

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值