专题二 - 滑动窗口 - 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 ) 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

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

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

相关文章

html5cssjs代码 016 表格示例

html5&css&js代码 016 表格示例 一、代码二、解释 这段HTML代码定义了一个网页&#xff0c;展示了不同类型的表格示例。页面使用了CSS样式来控制字体颜色、背景颜色、表格样式等。 一、代码 <!DOCTYPE html> <html lang"zh-cn"> <head>&l…

OpenResty使用Lua大全(一)Lua语法入门实战

文章目录 系列文章索引一、OpenResty使用Lua入门1、hello world2、nginx内部变量 二、Lua入门1、简介1、hello world2、基本语法&#xff08;1&#xff09;注释&#xff08;2&#xff09;数据类型&#xff08;3&#xff09;变量&#xff08;4&#xff09;函数&#xff08;5&…

【Java中的数组Array】

Java中的数组Array 一、数组的创建 package space.goldchen;/*** 数组初始化&#xff0c;数组定义** author 2021* create 2023-12-14 14:14*/ public class ArrayInit {public static void main(String[] args) {// 数组的初始化的三种方式int[] arr1 new int[5];int[] arr…

c++基础语法

文章目录 前言命名空间命名空间的使用 缺省参数缺省参数的使用 函数重载函数重载的作用函数重载的使用函数重载原理 引用引用的使用引用的使用场景引用和指针 extern Cinlineauto范围fornullptr 前言 大家好我是jiantaoyab&#xff0c;这篇文章给大家带来的是c语言没有的一些特…

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——遗传算法(GA)

基于python语言&#xff0c;采用经典遗传算法&#xff08;GA&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前已经成熟的…

Android 配置打包签名信息的两种方法

目录结构如下&#xff1a; 有2种方式&#xff1a; 第一种&#xff0c;直接配置&#xff1a; signingConfigs { debug { storeFile file("app/keystore.properties") storePassword "111111" keyAlias "key" keyPassword "111111" } …

Redis 订阅发布(Pub/Sub) 详解 如何使用订阅发布

Pub/Sub (发布订阅) Redis的发布订阅&#xff08;Pub/Sub&#xff09;是一种消息传递模式&#xff0c;它允许消息的发送者&#xff08;发布者&#xff09;将消息发送到通道&#xff0c;而订阅者则可以订阅一个或多个通道&#xff0c;并接收发布者发送到这些通道的消息。发布订…

学习记录之数学表达式(1)

文章目录 一、概述二、符号表2.1 常用符号表2.2 希腊字母表 三、集合的表示与运算3.1 集合的表示3.2 元素与集合3.3 集合的运算3.4 幂集3.5 笛卡尔积3.6 作业 一、概述 本系列内容参考闵老师的博客&#xff1a;数学表达式: 从恐惧到单挑 (符号表) &#xff08;1&#xff09;数学…

【Java】bigdecimal转为string时会变成科学计数法 | 大数取消转换为科学计数法

遇见“隐形刺客” 在银行写代码&#xff0c;我们通常用BigDecimal来处理大数计算&#xff0c;确保精度无损&#xff0c;正所谓“精打细算”。然而&#xff0c;当你满怀信心地将BigDecimal转换为String&#xff0c;准备输出或存储时&#xff0c;突然发现它变成了一串让人眼花缭…

Linux 服务器挂载盘阵(运维工程师必备技能难度***)

以下为真实操作过程 [rootdg1 ~]# fdisk -l -uDisk /dev/sda: 32.2 GB, 32212254720 bytes 255 heads, 63 sectors/track, 3916 cylinders, total 62914560 sectors Units sectors of 1 * 512 512 bytesDevice Boot Start End Blocks Id System /dev/s…

回归分析之boxcox

Box-Cox变换是一种用于处理非正态分布数据的统计方法。它通过对数据进行一系列的变换&#xff0c;将其转化为近似正态分布的形式&#xff0c;以便用于回归分析。 Box-Cox变换的基本思想是通过对数据应用一个参数λ的幂函数变换&#xff0c;其中λ可以是任意实数。具体而言&…

2022-6 青少年软件编程(图形化) 等级考试试卷(一级)

第1题:【 单选题】 广场中有声控喷泉, 当声音的音量大于 60 的时候, 喷泉就会喷出水, 现在的音量为30,下列哪个选项可以让喷泉喷出水? ( ) A: B: C: D: 【正确答案】: B 【试题解析】 : 当前声音的音量为 30, 需要将声音增加到 60 以上就可以让喷泉喷出水, …

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的日常场景下的人脸检测系统(深度学习模型+PySide6界面+训练数据集+Python代码)

摘要&#xff1a;开发用于日常环境中的人脸识别系统对增强安全监测和提供定制化服务极为关键。本篇文章详细描述了运用深度学习技术开发人脸识别系统的全过程&#xff0c;并附上了完整的代码。该系统搭建在强大的YOLOv8算法之上&#xff0c;并通过与YOLOv7、YOLOv6、YOLOv5的性…

HTML5:七天学会基础动画网页12

“书接上回”继续对transition补充&#xff0c;在检查中找到ease后&#xff0c;鼠标放到ease前的紫色小方块就可以对运动曲线进行调整&#xff0c;这个曲线叫贝塞尔曲线&#xff0c;这里不做别的补充&#xff0c;不用了解&#xff0c;我们只要知道这个运动方式不只是有简单的匀…

.Net Core 中间件验签

文章目录 为什么是用中间件而不是筛选器&#xff1f;代码实现技术要点context.Request.EnableBuffering()指针问题 小结 为什么是用中间件而不是筛选器&#xff1f; 为什么要用中间件验签&#xff0c;而不是筛选器去验签? 1、根据上图我们可以看到&#xff0c;中间件在筛选器之…

MySQL--彻底解决Navicat备份时的报错

原文网址&#xff1a;MySQL--彻底解决Navicat备份时的报错_IT利刃出鞘的博客-CSDN博客 简介 本文介绍彻底解决Navicat备份时的报错。 正确的方法 见&#xff1a;MySQL命令--使用mysqldump导出导入数据库_IT利刃出鞘的博客-CSDN博客 错误的方法 方法1.转储SQL文件 这种方…

2.2 塑性力学——主应力、主方向、不变量

个人专栏—塑性力学 1.1 塑性力学基本概念 塑性力学基本概念 1.2 弹塑性材料的三杆桁架分析 弹塑性材料的三杆桁架分析 1.3 加载路径对桁架的影响 加载路径对桁架的影响 2.1 塑性力学——应力分析基本概念 应力分析基本概念 2.2 塑性力学——主应力、主方向、不变量 主应力、主…

【嵌入式——QT】标准对话框

【嵌入式——QT】标准对话框 文件对话框颜色对话框字体对话框输入对话框消息框代码示例 文件对话框 QFileDialog 常用静态函数 getOpenFileName&#xff1a;选择打开一个文件&#xff1b;getOpenFileNames&#xff1a;选择打开多个文件&#xff1b;getSaveFileName&#xff1…

【算法面试题】-07

小明找位置 题目描述 小朋友出操&#xff0c;按学号从小到大排成一列;小明来迟了&#xff0c;请你给小明出个主意&#xff0c;让他尽快找到他应该排的位置。 算法复杂度要求不高于nLog(n);学号为整数类型&#xff0c;队列规模<10000; 输入描述 1、第一行:输入已排成队列的…

Vue中怎么使用router进行页面传参

在响应式编程中&#xff0c;使用 Vue Router 传递参数通常涉及到以下几个方面&#xff1a; 1. 动态路由匹配 动态路由匹配允许你根据 URL 中的参数来渲染不同的组件。这在显示用户信息、博客文章等需要根据 ID 或其他标识符来区分内容的情况下非常有用。 例如&#xff0c;如果…