滑动窗口练习1-长度最小的子数组

1.题目链接:209.长度最小的子数组

2.题目描述:

给定一个含有 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 <= 109

  • 1 <= nums.length <= 105

  • 1 <= nums[i] <= 105

进阶:

  • 如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

3.解法一(暴力求解)(会超时):

算法思路:

「从前往后」枚举数组中的任意一个元素,把它当成起始位置。然后从这个「起始位置」开始,然后寻找一段最短的区间,使得这段区间的和「大于等于」目标值。

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

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        //记录结果
        int ret = INT_MAX;
        int n = nums.size();
        //枚举出所有满足和大于等于 target 的子数组[start,end]
        //由于是取到最小,因此枚举的过程中要尽量让数组的长度最小
        //枚举开始位置
        for(int start = 0; start < n;start++){
            int sum = 0;//记录从这个位置开始的连续数组的和
            //寻找结束位置
            for(int end = start ;end < n ; end++){
                sum += nums[end];//将当前位置加上
                if(sum >= target)//当这段区间内的和满足条件时
                {
                    //更新结果,start 开头的最短区间已经找到
                    ret = min(ret , end - start +1);
                    break;
                }
            }
        }
        return ret == INT_MAX ? 0 : ret;
    }
};

4.解法二(滑动窗口):

算法思路:

由于此问题分析的对象是「一段连续的区间」,因此可以考虑「滑动窗口」的思想来解决这道题。

让滑动窗口满足:从 i 位置开始,窗口内所有元素的和小于 target (那么当窗口内元素之和第一次大于等于目标值的时候,就是 i 位置开始,满足条件的最小值)

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

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

  • 如果窗口内元素之和不满足条件:right++ ,另下一个元素进入窗口。

相信科学(这也是很多题解以及帖子没告诉你的事情:只给你说这么做。没给你解释为什么这么做):

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

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

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

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

  4. 这样我们不仅能解决问题,而且效率也会大大提升

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

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int len = INT_MAX;
        int n = nums.size();
        int sum = 0;
        for(int left = 0, right = 0; right < n ; right++){
            sum += nums[right];//进窗口
            while(sum >= target){//判断
                len = min(len,right-left+1);//更新结果
                sum -= nums[left++];//出窗口
            }
        }
        return len == INT_MAX ? 0 : len;
    }
};

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/722838.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】第9章 降维算法——PCA降维

一、概念 1.PCA &#xff08;1&#xff09;主成分分析&#xff08;Principal ComponentAnalysis&#xff0c;PCA&#xff09;一种经典的线性降维分析算法。 &#xff08;2&#xff09;原理&#xff0c;这里以二维转一维为例&#xff0c;原来的平面变成了一条直线 这是三维变二…

git 基本命令

列出分支基本命令&#xff1a; git branch 如果我们要手动创建一个分支 。执行 git branch (branchname) 即可&#xff1a; git branch testing 切换到testing分支&#xff1a; git checkout testing 我们也可以使用 git checkout -b (branchname) 命令来创建新分支并立…

1504 - Java多线程面试题

少年&#xff0c;思无邪&#xff0c;最最动人。 1.Java中有哪几种创建线程的方式 1.1 继承Thread类 代码示例 class HelloWorld01 extends Thread{Overridepublic void run() {System.out.println("这是继承 Thread 类方式实现多线程!");} }public class CreateTh…

Redis 高可用 sentinel

简介 Sentinel提供了一种高可用方案来抵抗节点故障&#xff0c;当故障发生时Redis集群可以自动进行主从切换&#xff0c;程序可以不用重启。 Redis Sentinel集群可以看成是一个Zookeeper集群&#xff0c;他是Redis集群高可用的心脏&#xff0c;一般由3-5个节点组成&#xff0…

从“产品的RFM分析”看如何探索“职业方向”

我们在做产品分析时&#xff0c;经常会用到一种方法“产品的RFM分析”&#xff0c;它是一种客户细分和价值评估的常用方法&#xff0c;广泛应用于电子商务、零售和其他众多行业&#xff0c;它可以帮助企业和产品团队更好地理解用户行为&#xff0c;优化营销策略&#xff0c;提升…

python发邮件给多人的注意事项?如何群发?

python发邮件给多人的效率如何&#xff1f;python发邮件的方法&#xff1f; 在利用Python编程语言实现邮件群发功能时&#xff0c;需要注意许多细节&#xff0c;以确保邮件能有效送达且用户体验良好。AokSend将详细探讨python发邮件给多人时需要注意的各个方面&#xff0c;以帮…

2024年历史、文学与人文艺术国际会议(ICHLH 2024)

2024年历史、文学与人文艺术国际会议&#xff08;ICHLH 2024&#xff09; 2024 International Conference on History, Literature, and Humanities 【重要信息】 大会地点&#xff1a;兰州 大会官网&#xff1a;http://www.ichlh.com 投稿邮箱&#xff1a;ichlhsub-conf.com 【…

【第10章】Vue之Element Plus常用组件

文章目录 前言一、表格1. 带斑马纹表格2. 展示 二、分页1.国际化(中文)2.分页代码3. 展示 三、表单1. 表单代码2. 展示 四、卡片1. 卡片代码2. 展示 总结 前言 通过上一章的快速入门&#xff0c;我们已经学习了按钮使用&#xff0c;接下来学习Element Plus的常用组件&#xff…

02-QWebEngineView的使用

Qt WebEngine_hitzsf的博客-CSDN博客 一、QWebEngineView QWebEngineView 类是一个实现Web浏览器的便捷类&#xff0c;提供了back() 、forward()、reload()、stop() 等方法&#xff0c;可轻松实现页面的前进、后退、重载等导航功能&#xff0c;要实现一个简单的只有网页加载网…

手机网站制作软件是哪些

手机网站制作软件是一种用于设计、开发和创建适用于移动设备的网站的软件工具。随着移动互联网时代的到来&#xff0c;越来越多的用户开始使用手机浏览网页和进行在线交流&#xff0c;因此&#xff0c;手机网站制作软件也逐渐成为了市场上的热门工具。 1. Adobe Dreamweaver&am…

前端某个页面乱码

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; springbootlayui&#xff0c;前后端一体 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 某个页面访问中文乱码&#xff1a; 就是这种。 不是数据库的中文&#xff0c;而是html页…

docker回顾--docker compose详细解释,安装,与常用命令

文章目录 Docker compose简介什么是Docker compose核心概念优势 安装常用命令总结 Docker compose简介 什么是Docker compose Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。它使得开发者可以使用一个单独的 YAML 文件来定义应用所需的所有服务、网络和卷&a…

智慧之选:Vatee万腾平台,引领未来的创新引擎

在数字化浪潮席卷全球的今天&#xff0c;我们身处一个信息爆炸、技术革新的时代。在这样的大背景下&#xff0c;选择一个能够引领我们走向未来的平台显得尤为重要。而Vatee万腾平台&#xff0c;正是这样一个不容错过的智慧之选。 Vatee万腾平台&#xff0c;作为一个集创新、科技…

uni app 树状结构数据展示

树状数据展示&#xff0c;可以点击item 将点击数据给父组件 &#xff0c;满足自己需求。不喜勿喷&#xff0c;很简单可以根据自己需求改哈&#xff0c;不要问&#xff0c;点赞收藏就好 <template><view><view v-for"(node, index) in treeData" :ke…

汇凯金业:现货黄金锁单及解锁策略详解

在现货黄金交易中&#xff0c;锁单是一种常见的操作手法&#xff0c;目的是在市场波动中保护已有盈利或避免亏损扩大。锁单分为锁损单和锁盈单&#xff0c;虽然锁单可以暂时控制风险&#xff0c;但解单操作不当可能会导致更大的损失。本文将详细介绍现货黄金锁单的概念、锁单的…

深入探索Stable Diffusion:从原理到应用的全面解析

目录 一 Stable Diffusion的基本概念 什么是Stable Diffusion? Stable Diffusion与传统生成模型的区别 二 Stable Diffusion的理论基础 扩散过程的数学描述 马尔可夫链蒙特卡罗方法(MCMC) 三 Stable Diffusion的算法实现 基本步骤 代码实现 四 Stable Diffusion的…

springboot优雅shutdown时如何保障异步线程的安全

我前面写了一篇springboot优雅shutdown的文章&#xff0c;看起来一切很美好。 https://blog.csdn.net/chenshm/article/details/139640775 那是因为没有进行多线程测试。如果一个请求中包括阻塞线程&#xff08;主线程&#xff09;和非阻塞线程&#xff08;异步线程&#xff09…

抖音短剧看剧系统是怎么做的?怎么样搭建上线运营?

前言&#xff1a; 当前热门短剧已深入大家的日常&#xff0c;针对一些好的短剧更是吸金无数。今天给大家介绍一下短剧这个项目整个运作模式。 一、一部短剧是怎么样呈现到观众眼前的&#xff1f; 首先影视作品公司拍摄剪辑好短剧 &#xff0c;弄好一切审核后&#xff0c;放到…

[C#] opencvsharp对Mat数据进行序列化或者反序列化以及格式化输出

【简要介绍】 在OpenCVSharp中&#xff0c;FileStorage类用于将数据&#xff08;包括OpenCV的Mat类型数据&#xff09;序列化为XML或YAML格式的文件&#xff0c;以及从这些文件中反序列化数据。以下是关于FileStorage类用法的详细说明&#xff1a; 写入数据&#xff08;序列化…

【分布预测】DistPred:回归与预测的无分布概率推理方法

论文题目&#xff1a;DistPred: A Distribution-Free Probabilistic Inference Method for Regression and Forecasting 论文作者&#xff1a;Daojun Liang, Haixia Zhang&#xff0c;Dongfeng Yuan 论文地址&#xff1a;https://arxiv.org/abs/2406.11397 代码地址&#xff1a…