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. 『无为则无心』Python基础 — 11、Python中的数据类型转换

    目录 1.为什么要进行数据类型转换 2.数据类型转换本质 3.数据类型转换用到的函数 4.常用数据类型转换的函数 (1)int()函数 (2)float()函数 (3)str()函数 (4)bool( ...

  2. NAT网络地址转换技术

    NAT网络地址转换技术 目录 一.NAT概述 1.1.概述 1.2.NAT 的应用场景 二.NAT的类型及配置命令 2.1.静态NAT 2.2.动态NAT 2.3.Easy IP 2.4.NATP 2 ...

  3. 单臂路由&链路捆绑

    单臂路由&链路捆绑 目录 一.单臂路由 1.1.单臂路由作用 1.2.单臂路由实现不同VLAN间通信的原理 二.单臂路由相关命令配置 三.链路捆绑 3.1.以太网链路聚合原理 3.2.命令配置 ...

  4. Golang中的各种时间操作

    Golang中的各种时间操作 需求 时间格式的转换比较麻烦,自己写了个工具,可以通过工具中的这些方法相互调用转成自己想要的格式,代码如下,后续有新的函数再添加 实现代码 package utils i ...

  5. kustomize简单使用

    1.背景 在Kubernetes v1.14版本的发布说明中,kustomize 成为了 kubectl 内置的子命令,并说明了 kustomize 使用 Kubernetes 原生概念帮助用户创作并 ...

  6. 乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时

    Dapr是一个由微软主导的云原生开源项目,国内云计算巨头阿里云也积极参与其中,2019年10月首次发布,到今年2月正式发布V1.0版本.在不到一年半的时间内,github star数达到了1.2万,超 ...

  7. SpringBoot缓存管理(一) 默认缓存管理

    前言 Spring框架支持透明地向应用程序添加缓存对缓存进行管理,其管理缓存的核心是将缓存应用于操作数据的方法(包括增删查改等),从而减少操作数据的执行次数(主要是查询,直接从缓存中读取数据),同时不 ...

  8. 21、nginx之ngx_http_proxy_module模块

    Nginx 的代理功能是通过 ngx_http_proxy_module 模块来实现的.默认在安装 Nginx 时已经安装了ngx_http_proxy_module模 块,因此可直接使用 ngx_h ...

  9. 在FLEX中真正的隐藏一个组件,隐藏后不占据自身的位置. (转)

    一直被这个问题困扰,就是在设置UI的Visible的时候,改组件的位置一直被占着,比较恶心,今天在这里发现了一个方法, 操作方法如下设置: includeInLayout为false即可 来自:htt ...

  10. 利用 FilesystemIterator 获取指定目录下的所有文件

    /** * 获取指定目录下的所有文件 * @param null $path * @return array */ public function getFileByPath($path = null ...