209. 长度最小的子数组

知识点:数组;前缀和;二分法;双指针;滑动窗口

题目描述

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。 输入:target = 4, nums = [1,4,4]
输出:1 输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

解法一:暴力法

使用两层for循环遍历;

class Solution {
public int minSubArrayLen(int target, int[] nums) {
int ans = Integer.MAX_VALUE;
for(int i = 0; i < nums.length; i++){
int sum = 0;
for(int j = i; j < nums.length; j++){
sum += nums[j];
if(sum >= target){
ans = Math.min(ans, j-i+1);
break;
}
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}

时间复杂度:0(N^2);

解法二:前缀和+二分法

这道题一看连续子数组触发了前缀和,前缀和就是用来解决连续子数组问题的,所以可以先统计到达每个的前缀和,仍然是为了方便,创建长度是n+1的数组,第一个位置放0,这样最后输出子数组长度的时候不用再去+1了,直接j-i就可以了。

前缀和之后,要想寻找子数组和大于target,就是找sum[i]-sum[j] >= target, 仍然需要遍历两遍,但是前缀和数组有一个重要的特点,就是是递增的(因为只有正数),所以这时候可以用二分搜索,将复杂度降低到O(logN),我们就是想找大于等于sum[i]+target的值.

在java中Arrays类有可以直接调用的Arrays.binarySearch(数组,目标值);如果能找到,就返回找到值的下标,如果没找到就返回一个负数,这个负数取反之后就是查找的值应该在原数组中的位置。

class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
int ans = Integer.MAX_VALUE;
int[] prenum = new int[n+1];
for(int i = 1; i <= n; i++){
prenum[i] = prenum[i-1] + nums[i-1];
}
for(int i = 0; i < n; i++){
int t = prenum[i] + target;
int index = Arrays.binarySearch(prenum, t);
if(index < 0) index = ~index; //负数的话取反是其应该在元素中的位置;其实也就是第一个比它大的值的元素;
if(index <= n){
ans = Math.min(ans, index-i);
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}

时间复杂度:0(NlogN);

解法三:滑动窗口

滑动窗口其实就是双指针的一种,只不过在移动过程中像是一个窗口在移动,所以称作滑动窗口,这是解决连续数组中一个很常见的思路;

可以定义两个指针start和end(分别表示窗口的开始和结束),end从头到尾去遍历数组,当移动出去之后遍历结束。在过程中,将nums[end]不断的加到sum上,如果sum>= target, 那就更新数组的最小长度,然后将nums[stat]在sum中减去,start前移,直到sum< target后,end再移;

class Solution {
public int minSubArrayLen(int target, int[] nums) {
int ans = Integer.MAX_VALUE;
int start = 0, end = 0;
int sum = 0;
while(end < nums.length){
sum += nums[end];
while(sum >= target){
ans = Math.min(ans, end-start+1);
sum -= nums[start]; //超过之后把前面的减去,窗口移动;
start++;
}
end++;
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}

时间复杂度:0(NlogN);

体会

连续子数组+和 --> 前缀和

相关链接

长度最小的子数组-看滑动窗口

长度最小的子数组-看前缀和

【LeetCode】209. 长度最小的子数组的更多相关文章

  1. Java实现 LeetCode 209 长度最小的子数组

    209. 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = ...

  2. Leetcode 209.长度最小的子数组 By Python

    给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums = [2, ...

  3. LeetCode 209. 长度最小的子数组(Minimum Size Subarray Sum)

    题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...

  4. LeetCode:长度最小的子数组【209】

    LeetCode:长度最小的子数组[209] 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 ...

  5. 领扣-209 长度最小的子数组 Minimum Size Subarray Sum MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 代码随想录第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

    2022/09/22 第二天 第一题 这题我就直接平方后排序了,很无脑但很快乐啊(官方题解是双指针 第二题 滑动窗口的问题,本来我也是直接暴力求解发现在leetCode上超时,看了官方题解,也是第一次 ...

  7. **209. Minimum Size Subarray Sum 长度最小的子数组

    1. 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nu ...

  8. LeetCode 长度最小的子数组

    题目: 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度.如果不存在符合条件的连续子数组,返回 0. 思路: 非常明显用滑动窗口处 ...

  9. leetcode209. 长度最小的子数组

    双指针滑动窗口解法,时间复杂度O(N). 滑动窗口,想象一下,在一个坐标上存在两个指针begin 和i ,begin 代表滑窗的左边框,i代表滑窗的右边框.两者通过分别向右滑动,前者能使窗口之间的和减 ...

随机推荐

  1. VBS脚本编程(2)——运算符

    算数运算符 用于执行数学计算的运算符. 1.加法运算符( + ) 计算两个数之和. 2.减法运算符( - ) 计算两个数值的差或表示数值表达式的负值. 3.乘法运算符(*) 计算两个数之积. 4.除法 ...

  2. IDEA拷贝类路径

    1.方法一 1.1.鼠标右击需要复制的类 1.2.点击 Copy Reference 2.方法二 快捷键:Ctrl + Alt + Shift + C

  3. 对volatile的理解--从JMM以及单例模式剖析

    请谈谈你对volatile的理解 1.volitale是Java虚拟机提供的一种轻量级的同步机制 三大特性1.1保证可见性 1.2不保证原子性 1.3禁止指令重排 首先保证可见性 1.1 可见性 概念 ...

  4. 一文带你了解.Net信号量

    本文主要讲解.Net基于Semaphore带大家了解信号量 信号量举例 大家去银行去银行取钱,互斥锁管理的时一个柜台是否正在处理业务,而信号量管理的是整个柜台是否正在处理业务,每当有一个柜台处理完成之 ...

  5. Elasticsearch的配置学习笔记

    文/朱季谦 Elasticsearch是一个基于Lucene的搜索服务器.它提供一个分布式多用户能力的全文搜索引擎,基于RESTful web接口,Elasticsearch是用Java语言开发的. ...

  6. keycloak~自定义rest接口

    rest资源 对于我们集成keycloak来说,你可能会遇到它没有实现的功能,这时需要对kc进行扩展,资源的扩展是其中一个方面,它需要实现RealmResourceProvider和RealmReso ...

  7. Gym 100283F Bakkar In The Army

    数学公式: n^2的前n项和n(n+1)(2*n+1)/6,用二分进行查找: 算出层数后继续二分查找位于这一层的哪一位,也可以推出相应公式 #include <iostream> #inc ...

  8. k8s结合jumpserver做kubectl权限控制 用户在多个namespaces的访问权限 rbac权限控制

    圈子太小,做人留一面,日后好相见. 其实这个文章就是用户用jumpserver登录到k8s master节点 然后执行kubectl的时候只有自己namespaces的所有权限. 背景 1,k8s 有 ...

  9. 暑假自学java第四天

    今天学习了类 1,声明并实例化 :类名    对象名  =   new   类名([参数1 ,参数2,....]):例:Car bus =new car (); 2,调用类的方法 :对象名.方法名(参 ...

  10. Docker:redis容器使用redis.conf启动失败,不报错

    查看redis.conf配置信息 daemonize no :redis默认是不作为守护进程使用的,这也就是说为什么在你不修改配置文件时直接使用redis-server /redis/redis.co ...