返回 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

这道题的关键在于我们要知道各个区间的和。从而来判断哪个区间的和是满足要求的。用暴利解法逐个判断是可行的,但是耗费的时间太多。因为暴力解法其实做了很多重复的工作。那么为了节省重复的计算,有个方法就是保存数组的前缀和数组。也就是用一个数组sum来记录各个区间的和。也就是

sum[i]=arr[0]+arr[1]+……+arr[i-1]。这里为了计算方便,增加了以为sum[0]=0。有了这个数组,就可以很方便的求解任意区间的和。

比如要求区间[4,6]的和,就可以用sum[6]-sum[4]。

那么接下来的工作就是要将sum数组中的各个求和值入队列。

(1) 当区间[0,i]的值比[0,i-1]的值要大的时候,就直接进队列。

(2) 当区间[0…i]的值比区间[0….i-1]还要小的时候,那么对于后面的位置,其实可以忽略掉i-1,因为sum[n]-sum[i] > sum[n]-sum[n-1]。也就是[i,n]区间的值比[i-1,n]的值要大,而且更短。因此i-1这个位置就可以被踢出队列。

比如队列里面的数值如下:0,1,3,5,4。由于4比5小,此时应该将5剔除出队列,为什么呢,如果保留5在队列里面,当后面一个数组比如7进队列的时候,队列数组变成0,1,3,5,4,7。 这个时候计算区间和7-5明显比7-4要小。而且[5,7]的区间长度为2,[4,7]的区间长度为1。因此5没有必要存在于队列中。队里中的值变为0,1,3,4,7

每次完成队列插入的操作后,就要开始对队列里面的区间进行计算了。

当队列为0,1的时候,1-0<4 不满足条件

当队列为0,1,3的时候,3-1<4 不满足条件

当队列为0,1,3,5的时候,5-0>4 满足条件,最小长度为3。0出队列,队列变为1,3,5
继续比较5-1>4,最小长度为2,1出队列,队列变为3,5。

当队列为3,4的时候(由于5比4小,因此出队列), 4-3<4不满足条件

当队列为3,4,7的时候,7-3>=4,满足条件,最小长度为2

代码如下:

没有采用队列或者栈的结构,就用数组来存储dquue,用dq_begin, dq_end, dq_size来分别表示数组的第一个,最后一个元素以及数组长度。

int shortestSubarray(int a[], int k, int len)

{

int *dqueue;

int *sum;

int
i,dq_begin,dq_end,dq_size,min_length,lengh;

dqueue = (int *)malloc((len + 1) * sizeof(int));

sum = (int *)malloc(len * sizeof(int));

memset(sum, 0,len * sizeof(int));

memset(dqueue, 0, (len + 1) * sizeof(int));

dq_begin = 0;

dq_end = -1;

dq_size = 0;

min_length = len+1;

for (i = 1; i
<= len; i++)

{

*(sum + i) = *(sum+i-1)+a[i-1];

}

for (i = 0; i
<= len; i++)

{

if (i != 0)

{

while (dq_size > 0 && sum[dq_end] >= sum[i])

{

dq_end -= 1;

dq_size -= 1;

}

while (dq_size > 0 && sum[i] - sum[dq_begin] >= k)

{

lengh = i - dq_begin;

min_length = min_length >=
lengh ? lengh : min_length;

dq_begin += 1;

dq_size -= 1;

}

}

dq_end += 1;

dqueue[dq_end] = i;

dq_size += 1;

}

return min_length;

}

和至少为K的最短子数组的更多相关文章

  1. 【LeetCode】862. 和至少为 K 的最短子数组

    862. 和至少为 K 的最短子数组 知识点:单调:队列:前缀和 题目描述 返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K . 如果没有和至少为 K 的非空子数组,返回 -1 . 示例 ...

  2. [LeetCode] 862. Shortest Subarray with Sum at Least K 和至少为K的最短子数组

    Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K. If there ...

  3. [Swift]LeetCode862. 和至少为 K 的最短子数组 | Shortest Subarray with Sum at Least K

    Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K. If there ...

  4. 【LeetCode】974. 和可被 K 整除的子数组

    974. 和可被 K 整除的子数组 知识点:数组:前缀和: 题目描述 给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续.非空)子数组的数目. 示例 输入:A = [4,5,0,-2,-3, ...

  5. 209 Minimum Size Subarray Sum 大于给定和最短子数组

    给定一个含有 n 个正整数的数组和一个正整数 s , 找到一个最小的连续子数组的长度,使得这个子数组的数字和 ≥  s .如果不存在符合条件的子数组,返回 0.举个例子,给定数组 [2,3,1,2,4 ...

  6. 974.和可被K整除的子数组

    题目 给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续.非空)子数组的数目. 示例: 输入:A = [4,5,0,-2,-3,1], K = 5 输出:7 解释: 有 7 个子数组满足其元 ...

  7. 【LeetCode/LintCode】 题解丨字节跳动试题:第k大的子数组

    给定一个长度为n的数组a,它有n(n+1)/2​​个子数组.请计算这些子数组的和,然后按照升序排列,并返回排序后第k个数. 1≤n≤10​^5 1≤a​i≤10^​9 1≤k≤​n(n+1)/2 在线 ...

  8. 算法——和为K的连续子数组

    给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] 为两种不同的情况. 链 ...

  9. Leetcode 974 和可被K整除的子数组

    题目: 解法 //前缀和算法+hash表 class Solution { public: int subarraysDivByK(vector<int>& A, int K) { ...

随机推荐

  1. 在github上优雅的搭建个人博客

    前言 啊啊啊---,经过差不多两天的持续摸索优化,个人博客算是初步完成了,现在自己看的效果还是非常不错的.这篇文章就是讲我怎么搭建一个这样的博客的.早在17年的时候就用hexo 结合github搭建过 ...

  2. P2220 [HAOI2012]容易题[小学数学]

    题目描述 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下: 有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定 ...

  3. python应用-跑马灯

    import os import time def main(): str1='欢迎来到前锋学习Python' while True: os.system('cls') print(str1) tim ...

  4. 题解:[HAOI2008]下落的圆盘

    时空限制:1000ms / 128MB 原题链接: 洛谷 bzoj Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红 色线条的 ...

  5. scanner=new Scanner(System.in); int i=scanner.nextInt();

    import java.util.Scanner; public class TryScanner { /** * @param args */ public static void main(Str ...

  6. Spring Boot 2.x(十六):玩转vue文件上传

    为什么使用Vue-Simple-Uploader 最近用到了Vue + Spring Boot来完成文件上传的操作,踩了一些坑,对比了一些Vue的组件,发现了一个很好用的组件--Vue-Simple- ...

  7. Vue——核心思想--mvvm

    Vue的核心思想为数据驱动和组件化. 一.数据驱动——双向绑定 Vue是一种MVVM框架.而DOM是数据的一个种自然映射.传统的模式是通过Ajax请求从model请求数据,然后手动的触发DOM传入数据 ...

  8. [Schematics] 2. EJS

    Schematices using EJS as template language. template: <%# This will not appear in the generated o ...

  9. LeetCode 499. The Maze III

    原题链接在这里:https://leetcode.com/problems/the-maze-iii/ 题目: There is a ball in a maze with empty spaces ...

  10. HDU 4828 小明系列故事——捉迷藏

    漂亮妹子点击就送:http://acm.hdu.edu.cn/showproblem.php?pid=4528 Time Limit: 500/200 MS (Java/Others)    Memo ...