最大连续1的个数 Ⅲ【滑动窗口】

文章目录

  • 往期滑动窗口
  • 上上期:滑动窗口
    • 0.1分析
    • 0.2 暴力求解【超时】
    • 0.3 滑动窗口
  • 上期: 滑动窗口
    • 1.1暴力+哈希
    • 1.2滑动窗口
  • 本期

往期滑动窗口

上上期:滑动窗口

在这里插入图片描述在这里插入图片描述

0.1分析

这道题要求的是一个区间 是区间就有【第一个元素】 即起始位置

0.2 暴力求解【超时】

这道题是要找一个子区间,使得这个区间的所有数 >= target;
把数组中的每⼀个元素作为一个区间的起始位置,每次往这个区间里加一个数,直到这个区间的数和>=target;将所有元素作为起始位置所得的结果中,找到「最⼩值」即为最短子区间。
在这里插入图片描述

class Solution
{
public:
    int minSubArrayLen(int target, vector<int> &nums)
    {
        // 记录结果
        int ret = INT_MAX;
        int n = nums.size();
        for (int start = 0; start < n; start++)
        {
            int sum = 0;
            for (int end = start; end < n; end++)
            {
                sum += nums[end];

                if (sum >= target)
                {
                    ret = min(ret, end - start + 1);
                    break;
                }
            }
        }
        return ret == INT_MAX ? 0 : ret;
    }
};

0.3 滑动窗口

铺垫

滑动窗口的思想实际上是基于【暴力求解】的优化。一般人/普通人在解这类题时,一般直接想到的解决方案就是【暴力求解】,但是我们都知道,【暴力求解】通常不是一个问题的最优方案。基于【暴力求解】,佬们就总结出来在【暴力求解】基础之上的优化,这个优化对于有“算法”思想的人来说不难想到/理解,关键在于有没有用心思考更优解。

讲解

【暴力求解】中提到,遍历数组,把每一个元素作为【结果区间】的首元素,依次顺序添加直到满足条件,记录将该元素作为【结果区间】首元素下【结果区间】的长度,遍历结束后,在取这些值的最小值即为结果。
现在我们细思【暴力求解】的过程,当把arr[0]作为【结果区间】的首元素时,我们计算求和了一部分值,当下一轮把arr[1]作为【结果区间】的首元素时,我们又重新计算了在第一轮中计算过的值,这就是【暴力求解】效率低下的原因。
学过数据结构我们知道,提升一个算法的时间复杂度,我们可以通过减少语句的执行/循环的次数/递归的次数等。在这道题中,有没有一种方法,使得我们能够减少计算的次数?

解答
在这里插入图片描述

第一个区间计算完之后,计算第二个区间时,实际上就是把【该区间首元素的前一个元素】即(遍历的上一个元素)移除,对于移除后的新区间

  1. 仍有可能满足条件【左端元素可能很小,划出去之后依旧满⾜条件】
  2. 不满足,即变小了。我们不再从arr[1]开始继续往后添加元素,而是把第一个区间去除arr[0]的剩余元素直接拿过来用,在这个【旧区间】的基础上再添加。

如此大大的减少了计算的次数。
在这里插入图片描述

代码

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++];             
            }
        }
        return len == INT_MAX ? 0 : len;
    }
};

上期: 滑动窗口

在这里插入图片描述
在这里插入图片描述

1.1暴力+哈希

枚举「从每⼀个位置」开始往后,⽆重复字符的⼦串可以到达什么位置。找出其中⻓度最⼤的即可。
在往后寻找⽆重复⼦串能到达的位置时,可以利⽤「哈希表」统计出字符出现的频次,来判断什么时候⼦串出现了重复元素。

class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        int ret = 0;
        int n = s.length();
        for (int i = 0; i < n; i++)
        {
            int hash[128] = {0};
            for (int j = i; j < n; j++)
            {
                hash[s[j]]++;
                if (hash[s[j]] > 1)
                    break;
                ret = max(ret, j - i + 1);
            }
        }
        return ret;
    }
};

1.2滑动窗口

left:固定目前在访问的子串的起始位置
right:加入到滑动区间的元素下标。
将每一个元素x作为起始位置,right不断向字串添加元素,如果不重复则记录长度,如果重复了,left++表示当前的x作为起始位置的【无重复字符的最长子串】已找到,继续遍历,把下一个字符作为起始位置。【用while不用if】这里的while代码有两个作用:1. 原先的left推测出窗口,它对应的字符个数应当–;2. 原来子串中出现了重复字符,不知道与right重复的字符在哪里,例如:abcdd,a做起始位置的【长度】为4,a出窗口,b作为起始位置,仍有重复字符,b直接出窗口==》b在a后面,b到right的长度肯定小于a到right,顾只要没有去除重复字符,就一直往后移动就行了,不用更新b做起始位置的长度。

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

本期

在这里插入图片描述
共识:【滑动区间的长度即连续1的个数】。这道题其实很有趣,写题就不要怕题,混社会就不要怕事。看这道题:其实就是个滑动窗口,只要0的个数不超k,0就能当1用,一旦0的个数超k,那么要求的长度已达到,此时我们要:1. 让该区间的最左值出窗口。2. 如果该区间的最左值还为0,那么他出窗口的同时,记录的0的个数还要–;

class Solution
{
public:
    int longestOnes(vector<int> &nums, int k)
    {
        int ret = 0;
        for (int left = 0, right = 0, zeroNum = 0; right < nums.size(); right++)
        {
            if (nums[right] == 0)
                zeroNum++;

            if (zeroNum > k)
            {
                if (nums[left] == 0)
                    zeroNum--;
                left++;
            }
            ret = max(ret, right - left + 1);
        }
        return ret;
    }
};

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

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

相关文章

算法学习——LeetCode力扣动态规划篇1(509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯、62. 不同路径、63. 不同路径 II)

算法学习——LeetCode力扣动态规划篇1 509. 斐波那契数 509. 斐波那契数 - 力扣&#xff08;LeetCode&#xff09; 描述 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项…

Nessus【部署 01】Linux环境部署漏洞扫描工具Nessus最新版详细过程分享(下载+安装+注册+激活)

Nessus最新版详细部署过程分享 1. 获取激活码2.主程序下载安装启动2.1 下载2.2安装2.3 启动 3.许可证及插件3.1 许可证获取3.2 插件安装 4.安装总结 Nessus官方网站&#xff1a; https://www.tenable.com/products/nessus/nessus-essentials 及介绍&#xff1a; 国际数据公司&…

WebUI自动化必备技能-HTML和css知识详解

学习web自动化的前提条件&#xff1a;手工测试&#xff08;了解各种测试的知识&#xff09;、学习编程语言、学习Web基础、学习自动化测试工具 、学习自动化测试框架 、需要掌握前端的一些知识&#xff0c;无论学习语言还是前端知识&#xff0c;都是为了接下来的脚本和框架做铺…

DIY 3 种分库分表分片算法,自己写的轮子才吊!

大家好&#xff0c;我是小富&#xff5e; 前言 本文是《ShardingSphere5.x分库分表原理与实战》系列的第六篇&#xff0c;书接上文实现三种自定义分片算法。通过自定义算法&#xff0c;可以根据特定业务需求定制分片策略&#xff0c;以满足不同场景下的性能、扩展性或数据处理…

常见微服务的组件?

注册中心&#xff1a;就是一个服务注册的地方&#xff0c;我们可以把拆分的服务注册到注册中心&#xff0c;这样注册中心就能管理这些服务&#xff0c;服务之间的调用就会很方便&#xff0c;通过服务名就能相互调用。 负载均衡&#xff1a;被调用放的负载均衡&#xff0c;比如…

单位K与ROM/RAM地址转化的关系?

文章目录 如题如图 如题 在单片机开发中&#xff0c;经常会见到多少K空间这样的字眼&#xff1f;我经常会忘记两者之间的关系&#xff0c;每次都要回想一下&#xff0c;才能明白&#xff0c;这次作为笔记记录一下 如图 这是我以前的笔记&#xff0c;平常所说的多少K是指多少K…

如何在jmeter中快速开发性能脚本?这个功能你需要知道。

在使用jmeter做性能测试时 &#xff0c;基本都是针对以下的两种类型的性能测试&#xff1a; 对web系统页面的性能测试 对系统的接口进行性能测试 有页面的可以优先测试页面 &#xff0c;但是如果是APP或小程序的性能测试 &#xff0c;更多的是对接口进行性能测试 。那么接下来…

学会这几点,是搭建产品知识库的关键

现如今&#xff0c;企业都特别看重产品知识库&#xff0c;因为有了它&#xff0c;企业就能更好地管理产品信息&#xff0c;提升客户服务水平&#xff0c;还能帮企业做决策。但是&#xff0c;搭建一个好用、高效的产品知识库&#xff0c;也难倒了不少人。下面&#xff0c;我们一…

记录何凯明在MIT的第一堂课:神经网络发展史

https://www.youtube.com/watch?vZ5qJ9IxSuKo 目录 表征学习 主要特点&#xff1a; 方法和技术&#xff1a; LeNet 全连接层​ 主要特点&#xff1a; 主要特点&#xff1a; 网络结构&#xff1a; AlexNet 主要特点&#xff1a; 网络结构&#xff1a; Sigmoid Re…

设备物联网关在某制造企业中的应用-天拓四方

随着物联网技术的迅猛发展&#xff0c;设备物联网关作为连接物理世界与数字世界的核心组件&#xff0c;其应用已经渗透到工业、农业、医疗等多个领域。本案例将聚焦于设备物联网关在某制造企业中的应用&#xff0c;详细解析其在实际生产中的重要作用。 案例背景 某制造企业面…

代码随想录阅读笔记-二叉树【平衡二叉树】

题目 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a;一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 返回 true 。 示例 2: 给定二叉树 [1,2,…

【Entity Framework】EF中的增删改查

【Entity Framework】EF中的增删改查 文章目录 【Entity Framework】EF中的增删改查一、概述二、DbContext数据上下文三、EntityState五个状态值四、EF添加数据4.1 EF Add方式4.2 EF 通过改变对象的状态为 Added4.3 调用方sql4.4 调用存储过程 五、EF修改数据5.1 不查询数据库&…

【SpringCloud】一文详谈Nacos

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 …

陀螺仪传感器,IMU和加速度计的产品和选型

爱普生陀螺仪传感器是一种角速度传感器&#xff0c;作为一种石英电子式陀螺仪芯片&#xff0c;具有温度特性好、功耗低、成本低、稳定性好等特点。目前EPSON主力单轴陀螺仪传感器型号为XV7001BB、XV7011BB、XV7021BB和XV7181BB。针对扫地机器人传感器模组等领域的需要&#xff…

享道出行:容器弹性技术驱动下的智慧出行稳定性实践

作者&#xff1a;郑嘉扬、何杉 前言 享道出行是一家专注于出行服务的专业品牌&#xff0c;是上汽集团实现汽车产业“新四化”&#xff08;即“电动化、智能网联化、共享化、国际化”&#xff09;的重要组成部分。作为上汽集团移动出行战略品牌&#xff0c;享道出行充分利用全…

4、jvm基础知识(四)

有哪些常见的垃圾回收算法&#xff1f; ⚫1960年John McCarthy发布了第一个GC算法&#xff1a;标记-清除算法。 ⚫1963年Marvin L. Minsky 发布了复制算法。 本质上后续所有的垃圾回收算法&#xff0c;都是在上述两种算法的基础上优化而来。 垃圾回收算法-标记清除算法 标记清…

“星际畅聊”来了!电子开启光通信,量子技术领航远程快速通讯

科学家们最近通过使用电脉冲将磁信息成功转换为偏振光信号&#xff0c;开启了一项革命性的量子技术。这一进展预示着未来包括地球与火星间长距离星际光通信在内的通信方式将发生翻天覆地的变化。 这项研究成果于3月27日在《自然》杂志上发表。研究聚焦于自旋电子学领域&#xf…

Gerrit学习

安装Gerrit 以Ubuntu 20.04为例&#xff0c;安装Gerrit容器2.15版本 docker-compose.yml version: 3 services:gerrit:image: gerritcodereview/gerrit:2.15ports:- 8080:8080- 29418:29418volumes:- ./review_site:/var/gerrit/review_siteenvironment:- CANONICAL_WEB_URL…

算法——距离计算

距离计算常用的算法包括欧氏距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、余弦相似度等。这些算法在数据挖掘、机器学习和模式识别等领域中被广泛应用。 1.欧氏距离 欧式距离也称欧几里得距离&#xff0c;是最常见的距离度量&#xff0c;衡量的是多维空间中两个点之间的…

Docker容器、Serverless与微服务:腾讯云云原生架构技术实践案例集解析

前言 随着云原生技术的飞速发展&#xff0c;容器化和函数计算正成为企业和开发者关注的焦点。在这一潮流中&#xff0c;腾讯云凭借其卓越的技术实力和深厚的行业积累&#xff0c;发布了《2023腾讯云容器和函数计算技术实践精选集》&#xff0c;为我们提供了一份深入探索云原生…