学习笔记--算法(滑动窗口)9

server/2024/9/23 4:21:39/

长度最小的子数组

链接:

. - 力扣(LeetCode)

题目:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]

输出:2

解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例 2:

输入:target = 4, nums = [1,4,4]

输出:1

示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]

输出:0

提示:

1 <= target <= 10^9

1 <= nums.length <= 10^5

1 <= nums[i] <= 10^5


解法一

图解

算法思路

「从前往后」枚举数组中的任意⼀个元素,把它当成起始位置。然后从这个「起始位置」开始,然

后寻找⼀段最短的区间,使得这段区间的和「⼤于等于」⽬标值。

将所有元素作为起始位置所得的结果中,找到「最⼩值」即可。

代码省略,超时。


解法二(滑动窗口)

算法思路

由于此问题分析的对象是「⼀段连续的区间」,因此可以考虑「滑动窗⼝」的思想来解决这道题。让滑动窗⼝满⾜:从 i 位置开始,窗⼝内所有元素的和⼩于 target (那么当窗⼝内元素之和第⼀次⼤于等于⽬标值的时候,就是 i 位置开始,满⾜条件的最⼩⻓度)。

做法:将右端元素划⼊窗⼝中,统计出此时窗⼝内元素的和:

▪ 如果窗⼝内元素之和⼤于等于 target :更新结果,并且将左端元素划出去的同时继续判断是否满⾜条件并更新结果(因为左端元素可能很⼩,划出去之后依旧满⾜条件)

▪ 如果窗⼝内元素之和不满⾜条件: right++ ,另下⼀个元素进⼊窗⼝。

为何滑动窗⼝可以解决问题,并且时间复杂度更低?

▪ 这个窗⼝寻找的是:以当前窗⼝最左侧元素(记为 left1 )为基准,符合条件的情况。也就是在这道题中,从 left1 开始,满⾜区间和 sum >= target 时的最右侧(记为right1 )能到哪⾥。

▪ 我们既然已经找到从 left1 开始的最优的区间,那么就可以⼤胆舍去 left1 。但是如果继续像⽅法⼀ 样,重新开始统计第⼆个元素( left2 )往后的和,势必会有⼤量重复的计算(因为我们在求第⼀段区间的时候,已经算出很多元素的和了,这些和是可以在计算下次区间和的时候⽤上的)。

▪ 此时, rigth1 的作⽤就体现出来了,我们只需将 left1 这个值从 sum 中剔除。从right1 这个元素开始,往后找满⾜ left2 元素的区间(此时 right1 也有可能是满⾜的,因为 left1 可能很⼩。 sum 剔除掉 left1 之后,依旧满⾜⼤于等于target )。这样我们就能省掉⼤量重复的计算。

▪ 这样我们不仅能解决问题,⽽且效率也会⼤ 提升。

时间复杂度:虽然代码是两层循环,但是我们的 left 指针和 right 指针都是不回退的,两者最多都往后移动 n 次。因此时间复杂度是 O(N) 。

图解

举例


代码

public int minSubArrayLen(int target, int[] nums) {int n = nums.length;int sum = 0;int len = Integer.MAX_VALUE;//由于在最开始的时候,如果len定义为0,就会导致在下面进行第一次出窗口比较len的时候,由于0比任何数都小,会导致输出结果为0,错误解答//left = 0,right = 0for(int left = 0,right = 0;right < n;right++){//进窗口sum += nums[right];//判断,如果sum>= target,就进行统计更新len,然后出窗口,再判断是否结束(right是否越界),未结束就让left++while(sum >= target){len = Math.min(len,right - left + 1);sum -= nums[left];left++; }}//如果没有找到满足target的子数组,就需要返回0return len == Integer.MAX_VALUE ? 0 : len; 
}


http://www.ppmy.cn/server/101640.html

相关文章

【15】大数据题目等

目录 一.大数据题目的解题技巧​编辑 二.找重复的URL 三.利用小内存找出所有出现两次的数。 四.位运算题目 五.面试原题 六,.判断一个32位正数是不是2的幂&#xff0c;4的幂 七.位运算实现加减乘除 加法 减法 乘法 除法 一.大数据题目的解题技巧 二.找重复的URL 方法…

RocketMQ学习

RocketMQ 如何保证消息不丢失 RocketMQ的消息想要确保不丢失&#xff0c;需要生产者、消费者以及Broker的共同努力&#xff0c;缺一不可。 首先在生产者端&#xff0c;消息的发送分为同步和异步两种&#xff0c;在同步发送消息的情况下&#xff0c;消息的发送会同步阻塞等待…

基于Spring Boot的企业产品档案管理系统

目录 前言 功能设计 系统实现 获取源码 博主主页&#xff1a;百成Java 往期系列&#xff1a;Spring Boot、SSM、JavaWeb、python、小程序 前言 随着企业规模扩张和产品种类增多&#xff0c;手动管理方式不再适应不断增长的需求。因此&#xff0c;本研究的目标是设计和开发…

负载均衡:HAProxy

1.安装&#xff1a; [root haproxy ~ ] # yum -y install ntpdate.x86_64 [root haproxy ~ ] # yum -y install ntp [root haproxy ~ ] # ntpdate cn.ntp.org.cn 13 Aug 19 : 39 : 27 ntpdate[ 1955 ] : adjust time server 120.197.116.202 offset 0.059032 sec…

springMVC访问不同位置的静态资源

resources和webapp目录结构如下图&#xff1a; 1. 访问webapp目录下的静态资源 1. 配置类 开启默认的servlet处理&#xff0c;处理webapp目录下的静态资源访问。需继承WebMvcConfigurer接口。 Configuration EnableWebMvc // 开启Spring MVC的注解驱动 ComponentScan(basePac…

实现基于TCP协议的服务器与客户机间简单通信

服务器端程序 #include <myhead.h> #define SER_PORT 6666 //服务器端口号 #define SER_IP "192.168.2.53" //服务器ip地址 int main(int argc, char const *argv[]) { /*创建套接字 int socket(int domain, int type, int protocol);*/ …

实战项目:贪吃蛇游戏的实现(上)

前言 Hello, 今天我们来一起完成一个实战项目&#xff1a;贪吃蛇。 相信大家都不会对这个游戏感到陌生&#xff0c;贪吃蛇游戏是久负盛名的游戏&#xff0c;他和俄罗斯方块&#xff0c;扫雷游戏等游戏位列世界经典游戏之列。这次我们旨在通过实战项目贪吃蛇的实现&#xff0c…

鸿蒙开发Location Kit(位置服务)如何设置

鸿蒙Location Kit 是一个强大的位置服务工具包&#xff0c;允许开发者在应用程序中集成精确的定位功能。Location Kit 提供了多种定位模式&#xff0c;支持室内和室外定位&#xff0c;并结合了GPS、Wi-Fi、蓝牙和基站等多种定位技术。 核心功能 精确定位&#xff1a;支持高精…