水果成篮

你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 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 <= fruits.length <= 105
0 <= fruits[i] < fruits.length

解题思路:

1. 使用两个指针left和right表示窗口的左右边界,初始时都指向数组的起始位置。
2. 使用一个哈希表(或者数组,因为题目说明fruits[i]的范围,但为了通用性,这里用哈希表)来记录当前窗口内各种水果的出现次数。
3. 右指针right不断向右移动,将遇到的水果加入窗口(即更新哈希表)。
4. 当窗口内水果种类超过2种时,移动左指针left,直到窗口内水果种类减少到2种(每次移动左指针,将左指针指向的水果从哈希表中移除,如果该水果数量减为0,则从哈希表中删除该种类)。
5. 在移动过程中,记录窗口的最大长度(即right-left+1),并更新最大长度。

具体步骤

初始化left=0, maxLen=0

使用一个HashMap来记录当前窗口内每种水果的出现次数,也可以使用数组(因为fruits[i] < fruits.length,所以数组长度可以设为fruits.length,但为了通用,这里用HashMap)

遍历right从0到len-1:
将fruits[right]加入HashMap(计数+1)
当HashMap的大小(即不同水果的种类)超过2时,开始移动左指针:
将fruits[left]从HashMap中移除(计数-1,如果减到0,则删除该键)
left++
此时窗口内的水果种类不超过2,更新最大长度:maxLen = max(maxLen, right-left+1)
但是,注意:在移动左指针的过程中,我们只需要移除直到窗口内水果种类重新变为2即可。因此,在移动左指针时,使用while循环直到HashMap大小<=2。

然而,实际上,由于每次只增加一个元素,因此当种类超过2时,我们只需要移动一次左指针(但是注意,可能一次移动并不够,因为可能移除了一个水果后,窗口内仍然有两种以上?实际上,由于我们每次移除一个,所以当种类超过2时,我们一直移动左指针直到种类等于2)。因此,内层使用while循环。

优化:由于我们使用HashMap记录每个水果出现的次数,当移除left位置的水果时,如果该水果在窗口内出现的次数减到0,那么我们就从HashMap中移除这个键,这样HashMap的大小就是当前窗口内的水果种类数。

代码实现

 public static int totalFruit(int[] fruits) {int n = fruits.length;// 频率数组:记录当前窗口中每种水果出现的次数// 数组大小设为n,因为水果种类范围是[0, n)int[] freq = new int[n];// 左指针:标记窗口起始位置int left = 0;// 最大长度:记录满足条件的最大窗口长度int maxLen = 0;// 种类计数:记录当前窗口中的水果种类数int count = 0;// 右指针遍历整个数组for (int right = 0; right < n; right++) {// 如果当前水果在窗口中首次出现,增加种类计数if (freq[fruits[right]] == 0) {count++;}// 增加当前水果的频率计数freq[fruits[right]]++;// 当窗口中水果种类超过2种时,需要缩小窗口while (count > 2) {// 减少左指针指向的水果的频率计数freq[fruits[left]]--;// 如果某种水果频率降为0,减少种类计数if (freq[fruits[left]] == 0) {count--;}// 左指针右移,缩小窗口left++;}// 更新最大窗口长度maxLen = Math.max(maxLen, right - left + 1);}return maxLen;}

代码解析: 初始化数据结构:

freq 数组:记录当前窗口中每种水果出现的次数(索引对应水果种类)

left 指针:标记滑动窗口的起始位置

maxLen:记录满足条件的最长子数组长度

count:记录当前窗口中的水果种类数

滑动窗口处理:

右指针扩展:right 指针从左到右遍历数组

新种类检测:当遇到窗口中未出现的水果种类时,增加种类计数 count

频率更新:增加当前水果在频率数组中的计数

窗口收缩:当种类数超过2时,移动左指针缩小窗口:

减少左指针指向水果的频率计数

如果某种水果频率降为0,减少种类计数

左指针右移

更新最大长度:每次循环后计算当前窗口长度并更新最大值

算法特性:

时间复杂度:O(n) - 每个元素最多被访问两次(右指针和左指针各一次)

空间复杂度:O(n) - 使用频率数组存储计数信息

最优性:滑动窗口确保在单次遍历中高效找到最优解

算法原理:
该问题本质是寻找最多包含两种不同元素的最长连续子数组。滑动窗口技术通过以下步骤解决:

窗口扩展:右指针不断向右移动,扩展窗口范围

状态维护:使用频率数组实时跟踪窗口内各元素数量

种类控制:当窗口内元素种类超过2时,左指针向右移动收缩窗口

结果更新:每次窗口调整后,记录满足条件的最大窗口长度

这种方法保证了在O(n)时间内找到最优解,尤其适合处理大规模数据(题目中数组长度可达10^5),是解决此类问题的最优方案。

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

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

相关文章

【Lua】题目小练8

-- 题目 1&#xff1a;定义一个类 Person-- 属性&#xff1a;name、age&#xff0c;其中 age 默认是 0&#xff0c;不能小于 0。-- 方法&#xff1a;introduce()&#xff0c;输出 "My name is <name>, I am <age> years old."-- 要求使用封装思想&#x…

SAP PP CK466

原因 作业价格没有维护 解决方案 KP26

如何解决pip安装报错ModuleNotFoundError: No module named ‘keras’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘keras’问题 摘要 在使用 PyCharm 进行深度学习项目开发时&#xff0c;常常需要通过 pip install keras 来安装 Keras 库。但有时即便命令执行成功&#xff0c…

人工智能领域、图欧科技、IMYAI智能助手2024年全年历史更新大事件汇总

2024年 2024年12月29日 【通知】 1、主站导出文档功能优化升级&#xff0c;新增支持了纯文本WORD导出功能&#xff0c;支持使用WPS软件打开 注&#xff1a;原来的富文本WORD不支持使用WPS打开&#xff0c;只支持系统自带的WORD软件打开&#xff0c;比如Microsoft Office Word 2…

UWB实操:使用UCI CMD测距;UCI CMD是一串数字,创建测距session,配置测距session,开始测距session。

使用UCI CMD测距; UCI CMD是一串数字,创建测距session,配置测距session,开始测距session。根据 FiRa_UCI_Technical_Specification,我们可以分析并组织测距cmd 例如: Fira2.0 1v1 发起 DSTWR 创建测距session:210000052222222200 配置测距session: 2103001F222…

从AUTOSAR角度理解CAN以及CANFD

一、AUTOSAR对CAN和CAN FD的基础定位 CAN&#xff1a;基于传统CAN 2.0B协议&#xff0c;是AUTOSAR早期版本&#xff08;如4.0.3及之前&#xff09;的核心车载通信协议&#xff0c;支持最大8字节 payload&#xff0c;仲裁段波特率通常≤1Mbps&#xff0c;适用于低带宽、高实时性…

第27章:服务部署与容器化

1. 课程引言 在前面的章节中&#xff0c;我们已经完成了电商项目核心服务的开发。然而&#xff0c;开发完成只是项目生命周期的一部分&#xff0c;如何将这些服务高效、可靠地部署到生产环境&#xff0c;是决定项目成败的关键一步。本章将聚焦于服务的部署&#xff0c;重点介绍…

力扣148:排序链表

力扣148:排序链表题目思路代码题目 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 思路 当我们第一眼看见这道题时心中其实是有思路的&#xff0c;我们不想这是个链表就当它是一个整型数组。那么自然而然就会想到各种各样的排序方法&#xf…

基于k8s环境下的pulsar常用命令(下)

#作者&#xff1a;Unstopabler 文章目录permissionSchemapermission pulsar的权限控制是在namespace级别的 kubectl exec pulsar-toolset-0 -n pulsar – bin/pulsar-admin namespaces grant-permission mytenant/mynamespace –actions produce,consume –role admin10 注…

2.4 组件通信

Props 和 Events&#xff08;父子组件通信&#xff09;Props&#xff1a;父组件向子组件传递数据使用 props。子组件通过声明 props 来接收来自父组件的数据。<!-- 父组件 --> <template><ChildComponent :message"parentMessage" /> </templat…

PCL学习之路-基础知识-(一)

文章目录1.西门子S7系列PLC类型划分(1).大型PLC&#xff1a;S7-400(2).中型PLC&#xff1a;S7-300(3).小型PLC&#xff1a;S7-200系列2.西门子S7外形结构(1).总览&#xff1a;PLC的“器官”分工逻辑3.输出电路(1).小型继电器输出形式(2).大功率晶体管/场效应管输出形式(3).双向…

leetcode654:最大二叉树(递归与单调栈双解法)

文章目录一、 题目描述二、 核心思路&#xff1a;分而治之与递归构造三、代码实现与深度解析四、 关键点与复杂度分析五、拓展解法单调栈解法两种解法对比LeetCode 654. 最大二叉树&#xff0c;【难度&#xff1a;中等&#xff1b;通过率&#xff1a;82.6%】&#xff0c;这道题…

Python 循环语法详解

在编程中&#xff0c;循环是一种非常常见的控制结构。很多时候&#xff0c;我们需要重复做一些事情&#xff0c;比如遍历列表、处理数据、尝试直到成功等。这时候&#xff0c;就离不开循环了。Python 提供了两种主要的循环结构&#xff1a;for 循环 和 while 循环。本篇文章会从…

一个小巧神奇的 USB数据线检测仪

一个小巧的数据线检测仪&#xff0c;检测各种USB数据线是否损坏、通断&#xff0c;TYPE_C、MICRO_B、苹果线、烧录线、网线都可检测。嵌入式开发者的称手工具。 这个是我个人制作的&#xff0c;SMT和连接器比较贵&#xff0c;特别是24PIN的C口连接器&#xff0c;我挂在黄色小鱼…

37.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--增加Github Action

在第二部分&#xff08;微服务基础工具与技术&#xff09;中我们讲解了GitHub Action的相关知识&#xff0c;那么在这一节中&#xff0c;我们将为已有的微服务增加GitHub Action的支持。 一、什么是GitHub Action 虽然前面已经介绍过GitHub Action的相关知识&#xff0c;但这里…

ROS2 通过 命令行 发布速度控制指令 控制 麦克娜姆轮

在 ROS2 中&#xff0c;要通过命令行发布速度控制指令来控制麦克娜姆轮机器人&#xff0c;你需要知道机器人所使用的速度控制话题和消息类型。通常麦克娜姆轮机器人使用geometry_msgs/Twist消息类型来接收速度指令。 以下是通过命令行发布速度控制指令的方法&#xff1a; 首先确…

多层Model更新多层ListView

一、总体架构QML (三层 ListView)└─ C 单例 DataCenter (QQmlContext 注册)├─ L1Model (一级节点)│ └─ 内部持有 QList<L2Model*>│ └─ L2Model (二级节点)│ └─ 内部持有 QList<L3Model*>│ └─ L3Model (三级节…

Git基础操作教程

本文目的是掌握Git基础操作教程一、Git简介Git&#xff1a;分布式版本控制系统&#xff0c;使用仓库(Repository)来记录文件的变化最流行的版本控制系统有两种&#xff1a;集中式&#xff08;SVN&#xff09;、分布式&#xff08;Git&#xff09;二、Git操作1.创建仓库仓库(Rep…

Android 之 Kotlin

变量变量的声明Kotlin使用var&#xff0c;val来声明变量&#xff0c;注意&#xff1a;Kotlin不再需要;来结尾var 可变变量&#xff0c;对应java的非final变量var b 1val不可变变量&#xff0c;对应java的final变量val a 1两种变量并未声明类型&#xff0c;这是因为Kotlin存在…

Design Compiler:布图规划探索(ICC)

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 简介 在Design Compiler Graphical中&#xff0c;可以用布图规划探索(Floorplan Exploration)功能&#xff0c;打开IC Compiler进行布图规划的创建、修改与分…