LeedCode刷题---滑动窗口问题

news2024/12/24 2:38:32

顾得泉:个人主页

个人专栏:《Linux操作系统》  《C/C++》  《LeedCode刷题》

键盘敲烂,年薪百万!


一、长度最小的子数组

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

题目描述

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

解法

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

算法思路:

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

解法二(滑动窗口):

算法思路:

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

做法:

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

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

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

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

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

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

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

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

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

代码实现

class Solution 
{
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        int n = nums.size(), sum = 0, len = INT_MAX;
        for(int left = 0, right = 0; right < n; right++)
        {
            sum += nums[right];
            while(sum >= target)
            {
                len = min(len, right - left + 1);
                sum -= nums[left];
                left++;
            }
        }
        return len == INT_MAX ? 0 : len;
    }
};

二、无重复字符的最长字串

题目链接:无重复字符的最长子串

题目描述

       给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc"        所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"        所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke"        所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke"        是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

解法

算法思路:

       研究的对象依旧是一段连续的区间,因此继续使用「滑动窗口」思想来优化。让滑动窗口满足:窗口内所有元素都是不重复的。

做法:

       右端元素ch进入茵口的时候,哈希表统计这个字符的频次:

       如果这个字符出现的频次超过1,说明窗口内有重复元素,那么就从左侧开始划出窗口,直到ch这个元素的频次变为1,然后再更新结果。

       如果没有超过1,说明当前窗口没有重复元素,可以直接更新结果

代码实现

class Solution 
{
public:
    int lengthOfLongestSubstring(string s) 
    {
        int hash[123] = {0};
        int left = 0, right = 0, ret = 0, n = s.size();
        while(right < n)
        {
            hash[s[right]]++;
            while(hash[s[right]] > 1)
                hash[s[left++]]--;
            ret = max(ret , right - left + 1);
            right++;
        }
        return ret;
    }
};

三、最大连续1的个数Ⅲ

题目链接:最大连续1的个数 III

题目描述

       给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

示例 1:

输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6

示例 2:

输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10

提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1
  • 0 <= k <= nums.length

解法

算法思路:

       不要去想怎么翻转,不要把问题想的很复杂,这道题的结果就是一段连续的1中间塞了k个0。

       因此,我们可以把问题转化成:求数组中一段最长的连续区间,要求这段区间内的0个数不超过k个。

       既然是连续区间,可以考虑使用「滑动窗口」来解决问题。

算法流程:

a.初始化一个大小为2的数组就可以当做哈希表hash 了;初始化一些变量left = 0,right = 0 , ret = 0;

b.当right小于数组大小的时候,一直下列循环:
     i.让当前元素进入窗口,顺便统计到哈希表中;

     ii.检查0的个数是否超标:

         如果超标,依次让左侧元素滑出窗口,顺便更新哈希表的值,直到的个数恢复正常;

     iii.程序到这里,说明窗口内元素是符合要求的,更新结果;iv. right++,处理下一个元素;

c.循环结束后,ret存的就是最终结果。

代码实现

class Solution 
{
public:
    int longestOnes(vector<int>& nums, int k) 
    {
        int ret = 0;
        for(int left = 0, right = 0, zero = 0; right < nums.size(); right++)
        {
            if(nums[right] == 0) 
                zero++;    
            while(zero > k)     
                if(nums[left++] == 0) 
                    zero--;   
            ret = max(ret, right - left + 1);   
        }
        return ret;
    }
};

结语:今日的刷题分享到这里就结束了,希望本篇文章的分享会对大家的学习带来些许帮助,如果大家有什么问题,欢迎大家在评论区留言~~~ 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL执行流程_执行一条select语句,期间发生了什么

文章目录 执行一条select语句&#xff0c;期间发生了什么MySQL执行流程第一步&#xff1a;连接器第二步&#xff1a;查询缓存第三步&#xff1a;解析SQL第四步&#xff1a;执行SQL 执行一条select语句&#xff0c;期间发生了什么 MySQL执行流程 server层负责建立连接、分析和执…

GraphSAGE 到底在训练什么? 图上的Mini-Batch 是怎么训练的 ?

1. 一个端到端的 同构图&#xff08;Cora数据集&#xff09;节点分类代码&#xff1a; import argparseimport dgl import dgl.nn as dglnnimport torch import torch.nn as nn import torch.nn.functional as F from dgl import AddSelfLoop from dgl.data import CiteseerGr…

YOLOv8训练好的pt文件如何用来预测

1. 使用原版预测 代码如下&#xff1a; from ultralytics import YOLO# Load a model model YOLO(yolov8n.pt) # load an official model# Predict with the model results model(https://ultralytics.com/images/bus.jpg) # predict on an image命令如下&#xff1a; y…

linux 17day 堡垒机 堡垒机下载 堡垒机安装 堡垒机使用 堡垒机管理服务器 堡垒机管理数据库

目录 堡垒机官网堡垒机下载堡垒机安装堡垒机使用Linux系统上使用web 使用配置站点url配置邮箱创建要管理的服务器创建 特权用户用于管理创建普通用户添加命令过滤命令过滤创建好 之后就需要 给用户名 和管理添加web用户登录 添加数据库mysql 服务区创建用户创建系统用户创建mys…

CRM对小微公司的实际作用:从客户管理到业务拓展

公司作为一个组织&#xff0c;管理方面是重中之重。传统式的人力会是一个较为费时费力的大工程。随着科技的发展&#xff0c;CRM系统完全可以胜任企业管理的工作。那么&#xff0c;CRM有什么特点&#xff1f;对小微公司有哪些作用&#xff1f; 1、提高管理效率 传统的客户管理…

DataFunSummit:2023年数据治理在线峰会-核心PPT资料下载

一、峰会简介 数据治理&#xff08;Data Governance&#xff09;是组织中涉及数据使用的一整套管理行为。由企业数据治理部门发起并推行&#xff0c;关于如何制定和实施针对整个企业内部数据的商业应用和技术管理的一系列政策和流程。 数据治理是一个通过一系列信息相关的过程…

MySQL笔记-第09章_子查询

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第09章_子查询1. 需求分析与问题解决1.1 实际问题1.2 子查询的基本使用1.3 子查询的分类 2. 单行子查询2.1 单行比较操作符2.2 代码示例2.3 …

生化危机5无法启动丢失xlive.dll怎么修复?快速修复教程分享

xlive.dll丢失的5个解决方法与xlive.dll文件丢失原因以及xlive.dll丢失对电脑有什么影响介绍 一、xlive.dll文件丢失原因&#xff1a; 1. 病毒或恶意软件感染&#xff1a;某些病毒或恶意软件会删除或损坏系统文件中的xlive.dll文件&#xff0c;导致其丢失。 2. 误操作&#…

作业12.12

1.闹钟 主函数 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);t new QTimer(this);idstartTimer(1000);speecher new QTextToSpeech(this); }Widget::~Wid…

QML WebEngineView 全屏和退出

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 在使用浏览器时,我们经常会用到全屏模式,最常见的场景有:观看视频、阅读文章、在线演示等。全屏模式的优点在于,它可以让用户充分地利用有限的屏幕空间,更好地专注于内容本身,从而提供丰富的沉浸式视觉…

视频剪辑入门:视频批量嵌套合并,成为视频编辑达人

随着数字媒体的快速发展&#xff0c;视频剪辑已经成为一项非常流行的技能。如果对视频剪辑感兴趣&#xff0c;想学习如何将多个视频批量嵌套合并&#xff0c;下面是云炫AI智剪批量嵌套合并视频的一些简单步骤&#xff0c;高效剪辑&#xff0c;成为视频编辑达人不再难。 准备要视…

金融银行软件测试超大型攻略,最受欢迎的金融银行大揭秘附面试题

零、为什么做金融类软件测试 举个栗子&#xff0c;银行里的软件测试工程师。横向跟互联网公司里的测试来说&#xff0c;薪资相对稳定&#xff0c;加班少甚至基本没有&#xff0c;业务稳定。实在是测试类岗位中的香饽饽&#xff01; 一、什么是金融行业 金融业是指经营金融商…

简单自定义vuex的设计思路

vuex集中式存储管理应用所有组件的状态&#xff0c;并以响应的规则保证状态以可预测的方式 发生变化。 步骤&#xff1a; 1.Store类&#xff0c;保存选项&#xff0c;_mutations&#xff0c;_actions&#xff0c;getters 2.响应式状态&#xff1a;new Vue方式设置响应式。 …

Java网络编程,使用UDP实现TCP(三), 基本实现四次挥手

简介 四次挥手示意图 在四次挥手过程中&#xff0c;第一次挥手中的Seq为本次挥手的ISN&#xff0c; ACK为 上一次挥手的 Seq1&#xff0c;即最后一次数据传输的Seq1。挥手信息由客户端首先发起。 实现步骤&#xff1a; 下面是TCP四次挥手的步骤&#xff1a; 第一次挥手&…

环境变量提权

环境变量提权 借鉴文章LINUX提权之环境变量提权篇 - 知乎 (zhihu.com) 利用条件 存在一个文件&#xff0c;利用su权限执行&#xff0c;普通用户可以执行此文件&#xff0c;但只限制在一个目录下可以执行 利用方式 将此文件的目录添加到环境变量中 export PATH/tmp:$PATHe…

分层自动化测试的实战思考!

自动化测试的分层模型 自动化测试的分层模型&#xff0c;我们应该已经很熟悉了&#xff0c;按照分层测试理念&#xff0c;自动化测试的投入产出应该是一个金字塔模型。越是向下&#xff0c;投入/产出比就越高&#xff0c;但开展的难易程度/成本和技术要求就越高&#xff0c;但…

Linux安装Halo(个人网站)

docker安装 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun && systemctl start docker && systemctl enable docker && sudo mkdir -p /etc/docker && sudo tee /etc/docker/daemon.json <<-EOF && sudo…

开题PPT答辩复盘

目录 总体思路加粗和红体字使用研究现状之后主要研究内容讨论 总体思路 分为五个部分&#xff0c;规定在10分钟以内讲完。这次开题答辩&#xff0c;主要是要讲清楚研究背景和意义&#xff0c;国内外研究现状。因此前两部分需要花大概6分钟重点解释&#xff0c;主要研究内容用2…

提升--22---ReentrantReadWriteLock读写锁

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 ReadWriteLock----读写锁1.读写锁介绍线程进入读锁的前提条件&#xff1a;线程进入写锁的前提条件&#xff1a;而读写锁有以下三个重要的特性&#xff1a; Reentran…

jQuery遍历与删除添加节点

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…