专题二 - 滑动窗口 - leetcode 904. 水果成篮 | 中等难度

leetcode 904. 水果成篮

  • leetcode 904. 水果成篮 | 中等难度
    • 1. 题目详情
      • 1. 原题链接
      • 2. 基础框架
    • 2. 解题思路
      • 1. 题目分析
      • 2. 算法原理
      • 3. 时间复杂度
    • 3. 代码实现
    • 4. 知识与收获

在这里插入图片描述

leetcode 904. 水果成篮 | 中等难度

1. 题目详情

你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘
给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。

示例 1:
输入:fruits = [1,2,1]
输出:3
解释:可以采摘全部 3 棵树。

示例 2:
输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。

示例 3:
输入:fruits = [1,2,3,2,2]
输出:4
解释:可以采摘 [2,3,2,2] 这四棵树。
如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。
示例 4:

输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
输出:5
解释:可以采摘 [1,2,1,1,2] 这五棵树。

提示:
1 < = f r u i t s . l e n g t h < = 1 0 5 1 <= fruits.length <= 10^5 1<=fruits.length<=105
0 < = f r u i t s [ i ] < f r u i t s . l e n g t h 0 <= fruits[i] < fruits.length 0<=fruits[i]<fruits.length

1. 原题链接

leetcode 904. 水果成篮

2. 基础框架

● Cpp代码框架

class Solution {
public:
    int totalFruit(vector<int>& fruits) {

    }
};

2. 解题思路

1. 题目分析

( 1 ) (1) (1) 本题是一道阅读理解题,首先理清题意:一个数组fruits,数组内的元素表示每棵树上水果的种类。我们从可以从任意一棵树开始采摘,但是每棵树只能采摘一次且只能向后移动,采摘的水果数量没有限制,但是只能采摘最多2种类型的水果。
类似于固定一个初始位置left,然后从左到右依次遍历数组fruits。题目又多了水果类型不超过2种的条件,所以在遍历数组fruits时需要额外记录水果类型和出现次数的对应关系,即key,val键值对。
( 2 ) (2) (2) 题目本质是求连续子数组的最大长度,只不过本题多了一个条件。
( 3 ) (3) (3) 先来看看暴力枚举思路:
left位置为起始位置,right从左到右依次遍历数组fruits,使用哈希表记录已遍历到子数组内水果类型及其出现的次数,len记录连续子数组的最大长度。
如果right位置的新水果加入后,水果类型 > 2,那么说明right及其之后的所有水果都不会满足连续子数组且水果类型不超过2了,right及其之后的位置也没有必要继续判断了,可以直接进行left在下一个位置的判断了;
如果right位置的新水果加入后,水果类型 <= 2,[left, right]位置的水果是满足条件的,所以更新len = max(len, right - left + 1)
对于每一次以新的left作为起始位置,right都要回退到left位置重新开始遍历,哈希表也需要清空,重新等待元素进入;
( 4 ) (4) (4)

2. 算法原理

( 1 ) (1) (1) 暴力枚举有什么可以优化的地方呢?
假设以某一个left为起始位置,rightleft开始向右依次遍历数组fruits,每次遍历的水果都进入哈希表hash
恰好本次right位置的新水果fruits[right]进入哈希表后,哈希表的元素[key,val]大于2,让我们定格在此:
暴力枚举的思路是:既然以left为起始的子数组已经不满足题意了,那么我left就右移,以新位置开始,哈希表hash清空,right回退并以新的left位置重新遍历数组frutis

在本次假设下,right位置元素是恰好不满足题意的,那么可知[left, right-1]区间的所有元素是一定满足题意的。
那么有必要让right回退到新left吗?哈希表hash有必要全部清空吗?

首先知道[left+1,right-1]区间一定是满足题意的,那么如果right回退到left+1位置,而[left+1,right-1]区间一定满足题意,那么该区间就会被重新遍历并以此加入哈希表hash,然后right又会来到回退之前的位置,在此位置可能有三种情况:right位置元素加入后
总水果类型小于等于2,那么right继续++向右遍历即可;
总水果类型还是大于2,那么left需要继续右移。
无论哪一种情况,right都不需要回退,只可能是不动或向右移动。
在这里插入图片描述

( 2 ) (2) (2) 滑动窗口
( 3 ) (3) (3) 初始化:left = 0, right = 0哈希表hash,长度记录len
( 4 ) (4) (4) 进窗口:right位置元素进入哈希表
( 5 ) (5) (5) 判断:在哈希表中水果类型 > 2时
( 6 ) (6) (6) 出窗口:哈希表hash中对应水果类型fruits[left]的计数–,特别的如果计数减到了0,说明没有此种类型水果了,需要在哈希表hasn中删除该类型,且left右移1位;
( 7 ) (7) (7) 更新结果: 到这一步说明[left, righ]范围内元素都是满足题意的,可以更新结果len = max(len, right-left)

3. 时间复杂度

暴力枚举 O ( n 2 ) O(n^2) O(n2)

滑动窗口 O ( n ) O(n) O(n)

只需遍历一遍数组

3. 代码实现

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        //unordered_map<int, int> hash;
        int hash[100001] = { 0 };
        int ret = 0;
        int l = 0, r = 0;
        int n = fruits.size();
        int kinds = 0;
        while(r < n){
            if(hash[fruits[r]] == 0) kinds++;
            hash[fruits[r]]++;//进窗口
            //while(hash.size() > 2){//判断
              while(kinds > 2){  
                hash[fruits[l]]--;//出窗口
                //if(hash[fruits[l]] == 0) hash.erase(fruits[l]);
                if(hash[fruits[l]] == 0) kinds--;
                l++;
            }
            ret = max(ret, r - l + 1);//更新结果
            r++;
        }
        return ret;
    }
};

4. 知识与收获

( 1 ) (1) (1) 本题需要先理清题意,找出本质:连续子数组的最大长度。


T h e The The E n d End End

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

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

相关文章

【SQL Server】实验六 数据安全性

1 实验目的 掌握用户管理的基本方法&#xff0c;包括创建用户、删除用户和设置用户密码。掌握用户授权和回收权限的基本方法。掌握系统级权限和对象级权限的授权和回收方法掌握角色的使用方法 2 实验内容 2.1 掌握用户管理的基本使用方法 创建用户&#xff08;带密码&#…

RTP 控制协议 (RTCP) 反馈用于拥塞控制

摘要 有效的 RTP 拥塞控制算法&#xff0c;需要比标准 RTP 控制协议(RTCP)发送方报告(SR)和接收方报告(RR)数据包提供的关于数据包丢失、定时和显式拥塞通知 (ECN) 标记的更细粒度的反馈。 本文档描述了 RTCP 反馈消息&#xff0c;旨在使用 RTP 对交互式实时流量启用拥塞控制…

【每日力扣】235. 二叉搜索树的最近公共祖先与39. 组合总和问题描述

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害。 235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义…

简易版 RPC 框架实现 2.0 -netty实现

这一篇理解如果有难度&#xff0c;可能对netty不是很理解&#xff0c; 可以关注我netty专栏&#xff0c;还有另外一篇&#xff1a; 用 Netty 自己实现简单的RPC&#xff0c; 这一篇是学习netty的时候写的&#xff0c;更倾向于分析netty相关的知识&#xff0c; 今天我是学习dubb…

Delphi7应用教程学习1.3【练习题目】:文本及悬停文字的显示

这个例子主要用到了btn的Hint 属性&#xff0c;Hint是提示的意思。 还有Delphi7还是很好用的&#xff0c;改变了的属性是粗体&#xff0c;默认没有改变的属性为细体。

插入排序:一种简单而有效的排序算法

插入排序&#xff1a;一种简单而有效的排序算法 一、什么是插入排序&#xff1f;二、插入排序的步骤三、插入排序的C语言实现四、插入排序的性能分析五、插入排序的优化六、总结 在我们日常生活和工作中&#xff0c;排序是一种非常常见的操作。比如&#xff0c;我们可能需要对一…

B端界面又丑又乱,也不会总结规范,来,我给5个规范模板,照着学

发5个别人总结的规范&#xff0c;一定会对你的B端系统改进&#xff0c;有帮助的。

TSINGSEE青犀AI烟火识别等算法打造电瓶车消防安全解决方案

一、背景分析 根据国家消防救援局的统计&#xff0c;2023年全国共接报电动自行车火灾2.1万起&#xff0c;相比2022年上升17.4%&#xff0c;电动自行车火灾安全隐患问题不容忽视。 电瓶车火情主要问题和原因&#xff1a; 电瓶车/电池质量良莠不齐用户安全意识薄弱&#xff0c…

虚拟机NAT模式配置

注意这里IP要和网关在同一网段&#xff0c;且虚拟机默认网关末尾为.2&#xff08;如果默认网关配置为.1会与宿主机冲突&#xff0c;导致无法ping通外网&#xff09; 点击NAT模式下的NAT设置即可查看默认网关 这里的网关可以理解为主机与虚拟机交互的入口

蓝桥杯算法训练VIP-数组查找及替换

题目 1634: 蓝桥杯算法训练VIP-数组查找及替换 时间限制: 3s 内存限制: 192MB 提交: 1629 解决: 890 题目描述 给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素&#xff0c;同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z的ASCII之间&#xff0…

MySQL:SQL优化

1. 插入优化 使用insert语句单条单条数据插入效率偏低&#xff0c;建议使用insert批量插入数据&#xff0c;批量控制在500-1000条数据较为合适&#xff0c;当面对数以百万的数据时&#xff0c;可以使用load指令&#xff0c;提升插入数据效率 相关指令 #客户端连接服务端加上参…

Java后端面试经验分享,~纯分享

本文将从面试、工作、学习三个方面分享最近面试的一些心得以及以后发展的一些规划&#xff0c;仅供参考&#xff0c;哈哈&#xff0c;毕竟本人也很菜&#xff0c;因为菜才要多学习。一会儿也会分享两本Java面试题库&#xff08;题库是b站大学找的&#xff0c;一会儿我也会分享出…

C# Onnx C2PNet 图像去雾 室内场景

目录 介绍 效果 模型信息 项目 代码 下载 C# Onnx C2PNet 图像去雾 室内场景 介绍 github地址&#xff1a;GitHub - YuZheng9/C2PNet: [CVPR 2023] Curricular Contrastive Regularization for Physics-aware Single Image Dehazing [CVPR 2023] Curricular Contrasti…

DataGrip 面试题及答案整理,最新面试题

DataGrip的数据库兼容性和多数据库支持如何实现&#xff1f; DataGrip实现数据库兼容性和多数据库支持的方式包括&#xff1a; 1、广泛的数据库支持&#xff1a; DataGrip支持多种数据库&#xff0c;包括但不限于MySQL, PostgreSQL, SQL Server, Oracle, SQLite, 和MongoDB&a…

C++:类之六脉神剑——默认成员函数

个人主页&#xff1a;日刷百题 系列专栏&#xff1a;〖C/C小游戏〗〖Linux〗〖数据结构〗 〖C语言〗 &#x1f30e;欢迎各位→点赞&#x1f44d;收藏⭐️留言&#x1f4dd; ​ ​ 一、默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为 空类 。 空类中真的什么都…

管理类联考–复试–政治--二十大--记忆宫殿

文章目录 整体记忆宫殿门床头柜床书桌阳台 口诀记忆法 整体 记忆宫殿 要有逻辑的放到房间了 何为逻辑&#xff0c;如下大佬总结的便是&#xff0c;或者可自行总结&#xff0c;有前后顺序&#xff0c;做事逻辑即可 第一步&#xff1a;将逻辑的点放到房间里的点&#xff0c;…

每日OJ题_简单多问题dp⑥_力扣714. 买卖股票的最佳时机含手续费

目录 力扣714. 买卖股票的最佳时机含手续费 状态机分析 解析代码 力扣714. 买卖股票的最佳时机含手续费 714. 买卖股票的最佳时机含手续费 难度 中等 给定一个整数数组 prices&#xff0c;其中 prices[i]表示第 i 天的股票价格 &#xff1b;整数 fee 代表了交易股票的手续…

cannot find -xml2: No such file or directory的解决方法

一&#xff0c;问题现象 在编译库的时候出现如下图所示的报错&#xff1a;C:/msys64/mingw32/bin/…/lib/gcc/i686-w64-mingw32/13.2.0/…/…/…/…/i686-w64-mingw32/bin/ld.exe: ca nnot find -lxml2: No such file or directory collect2.exe: error: ld returned 1 exit s…

spring boot集成redis实现共享存储session

spring boot集成redis实现共享存储session redis实现共享存储session 首先下载redis,我下载的版本是5.0.14,目前官网貌似找不到5.x版本&#xff0c;可以自行去网上寻找。我这里的springboot版本是2.6.4引入redis依赖 <!-- https://mvnrepository.com/artifact/org.spring…

火车订票管理系统|基于springboot框架+ Mysql+Java+B/S结构的火车订票管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 lunwen…