L48.【LeetCode题解】904. 水果成篮

目录

1.题目

2.分析

方法1:暴力枚举

方法2:暴力解法的优化:滑动窗口

代码

方法3:优化方法2:使用数组充当哈希表

方法4:四个变量分别充当篮子和篮子中水果的个数(最快!!!)

代码

容易忽略的点


1.题目

https://leetcode.cn/problems/fruit-into-baskets/

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

2.分析

需要使用set来统计[left,right]之间水果的种类数

方法1:暴力枚举

class Solution {
public:int totalFruit(vector<int>& fruits) {int left=0,right=0,ret=0;for (;left<fruits.size();left++){set<int> mp;for (right=left;right<fruits.size();right++){mp.insert(fruits[right]);if (mp.size()>2)break;}       ret=max(ret,right-left);}return ret;}
};

提交结果:超时

方法2:暴力解法的优化:滑动窗口

right不用每次都从left开始枚举,以这个为例:[1,2,1,2,3,2,3,3]

当mp.size()>2时,

left只需要向前移动,直到mp.size()\leqslant2时停止移动,能减少大量无用的循环,提高运行速度

使用存储双关键字类型的map<int,int>,第一个关键字存储类型,第二个关键字存储每类的水果的个数

可以先mp[fruits[right]]++(进窗口),看看mp.size()有没有超过2,如果超过,使mp[fruits[left++]]--(出窗口),如果发现减到0了,就erase(注:erase直接删除掉节点的所有信息, 不是让mp[x]置为0)

最后更新结果:ret=max(ret,right-left+1);

代码

class Solution {
public:int totalFruit(vector<int>& fruits) {map<int,int> mp;int left=0,right=0,ret=0; for (;right<fruits.size();right++){mp[fruits[right]]++;while (mp.size()==3){mp[fruits[left++]]--;if (mp[fruits[left-1]]==0)mp.erase(fruits[left-1]);}ret=max(ret,right-left+1);}return ret;}
};

提交结果:

当然也可以使用unordered_map解决:

但无论是map还是unordered_map对mp多次插入和删除比较耗时,时间复杂度较高,可以使用方法3:数组充当哈希表

方法3:优化方法2:使用数组充当哈希表

要多用一个变量kind来存储水果种类的数量,因为1 <= fruits.length <= 10^5 使用哈希数组hash[100001]来存储,哈希数组的特点正好符合对双关键字的要求,对于种类为x的水果,其个数为hash[x]

kind++的条件:hash[fruit[right]]从0变成1

kind--的条件:hash[fruit[right]]从1变成0

class Solution {
public:int totalFruit(vector<int>& fruits) {int hash[100001]={0};int left=0,right=0,ret=0,kind=0; for (;right<fruits.size();right++){hash[fruits[right]]++;if (hash[fruits[right]]==1)kind++;while (kind==3){hash[fruits[left++]]--;if (hash[fruits[left-1]]==0)kind--;}ret=max(ret,right-left+1);}return ret;}
};

提交结果:

方法4:四个变量分别充当篮子和篮子中水果的个数(最快!!!)

bkt1存储篮子1的水果种类数,篮子1的水果个数为bkt1_num(bkt为basket的简写)

bkt2存储篮子2的水果种类数,篮子1的水果个数为bkt2_num

代码

class Solution {
public:int totalFruit(vector<int>& fruits){int bkt1 = -1, bkt2 = -1, bkt1_num = 0, bkt2_num = 0;int left = 0, right = 0, ret = 0;for (; right < fruits.size(); right++){if (bkt1 == -1){bkt1 = fruits[right];bkt1_num++;}else if (bkt2 == -1&&fruits[right]!=bkt1){bkt2 = fruits[right];bkt2_num++;}else{if (fruits[right] == bkt1)bkt1_num++;else if (fruits[right] == bkt2)bkt2_num++;else//如果出现第三种水果{while (1){if (fruits[left] == bkt1)bkt1_num--;elsebkt2_num--;left++;if (bkt1_num == 0){bkt1 = fruits[right];bkt1_num++;break;}if (bkt2_num == 0){bkt2 = fruits[right];bkt2_num++;break;}}}}ret = max(ret, right - left + 1);}return ret;}
};

容易忽略的点

else if (bkt2 == -1&&fruits[right]!=bkt1)的fruits[right]!=bkt1不可以省,否则将无法通过[0,0,1,1]测试用例

提交结果:

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

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

相关文章

Leetcode-BFS问题

LeetCode-BFS问题 1.Floodfill问题 1.图像渲染问题 [https://leetcode.cn/problems/flood-fill/description/](https://leetcode.cn/problems/flood-fill/description/) class Solution {public int[][] floodFill(int[][] image, int sr, int sc, int color) {//可以借助另一…

Typora+PicGo+Gitee图床配置教程 自动图片上传

配置步骤 #mermaid-svg-aPUbWs43XR5Rh7vf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-aPUbWs43XR5Rh7vf .error-icon{fill:#552222;}#mermaid-svg-aPUbWs43XR5Rh7vf .error-text{fill:#552222;stroke:#552222;}#…

养生:开启健康生活的全新篇章

养生是一场关乎生活品质与身心健康的持续修行&#xff0c;从饮食调养到运动锻炼&#xff0c;从睡眠管理到心态塑造&#xff0c;每个环节都对健康有着深远影响。以下为你提供全面且实用的养生指南。 饮食养生&#xff1a;科学膳食&#xff0c;滋养生命 合理的饮食是养生的根基…

Python | 赤道频散关系图

写在前面 写开题报告&#xff0c; 想用个图发现截出来全是糊的。索性自己画了&#xff0c;主要实现的Matsuno&#xff08;1966&#xff09;的赤道波动频散关系图。但是&#xff0c;实在是没有审美&#xff0c;其他文献里都是黑色&#xff0c;这里非要用个紫色&#xff0c;因为…

Nexus 私有仓库 + Nginx 反向代理部署文档

1. 使用 Podman 部署 Nexus 3 podman run --name nexus -d \-p 8081:8081 \-v /data:/nexus-data \-v /etc/localtime:/etc/localtime \-e TZ"Asia/Shanghai" \-e INSTALL4J_ADD_VM_PARAMS"-Xms10240m -Xmx10240m -XX:MaxDirectMemorySize4096m" \docker.…

一.Gitee基本操作

一.初始化 1.git init初始化仓库 git init 用于在当前目录下初始化一个本地 Git 仓库&#xff0c;让这个目录开始被 Git 跟踪和管理。 生成 .git 元数据目录&#xff0c;从而可以开始进行提交、回退、分支管理等操作。 2.git config user.name/user.email配置本地仓库 # 设置…

力扣210(拓扑排序)

210. 课程表 II - 力扣&#xff08;LeetCode&#xff09; 这是一道拓扑排序的模板题。简单来说&#xff0c;给出一个有向图&#xff0c;把这个有向图转成线性的排序就叫拓扑排序。如果有向图中有环就没有办法进行拓扑排序了。因此&#xff0c;拓扑排序也是图论中判断有向无环图…

华为ensp实现跨vlan通信

要在网络拓扑中实现主机192.168.1.1、192.168.1.2和192.168.2.1之间的互相通信&#xff0c;需要正确配置交换机&#xff08;S5700&#xff09;和路由器&#xff08;AR3260&#xff09;&#xff0c;以确保不同网段之间的通信&#xff08;即VLAN间路由&#xff09;。 网络拓扑分析…

热部署与双亲委派

热部署初探与双亲委派机制 一、热部署初探 ​ 热部署就是在不重启服务的情况下&#xff0c;无需重新启动整个应用&#xff0c;就能对代码、配置等进行更新并使新的更改在服务中生效。以下代码可以打破双亲委派机制&#xff0c;利用类加载器的隔离实现热部署。可分为以下三步进…

AWS SNS:解锁高并发消息通知与系统集成的云端利器

导语 在分布式系统架构中&#xff0c;如何实现高效、可靠的消息通知与跨服务通信&#xff1f;AWS Simple Notification Service&#xff08;SNS&#xff09;作为全托管的发布/订阅&#xff08;Pub/Sub&#xff09;服务&#xff0c;正在成为企业构建弹性系统的核心组件。本文深度…

驱动开发硬核特训 · Day 30(下篇): 深入解析 lm48100q I2C 音频编解码器驱动模型(基于 i.MX8MP)

作者&#xff1a;嵌入式Jerry 视频教程请关注 B 站&#xff1a;“嵌入式Jerry” 一、背景与目标 在本篇中&#xff0c;我们围绕 TI 的 lm48100q 音频编解码器 展开&#xff0c;深入讲解其作为 I2C 外设如何集成至 Linux 内核音频子系统&#xff08;ASoC&#xff09;&#xff0…

idea写spark程序

步骤 1&#xff1a;创建 Maven 项目 打开 IntelliJ IDEA&#xff0c;选择 File > New > Project。选择 Maven&#xff0c;勾选 Create from archetype&#xff0c;选择 org.apache.maven.archetypes:maven-archetype-quickstart。填写 GroupId&#xff08;如 com.exampl…

【C语言练习】032. 编写带参数的函数

032. 编写带参数的函数 032. 编写带参数的函数1. 定义带参数的函数示例1:定义一个带参数的函数输出结果2. 传递多个参数示例2:定义一个带多个参数的函数输出结果3. 传递数组作为参数示例3:定义一个带数组参数的函数输出结果4. 传递结构体作为参数示例4:定义一个带结构体参数…

Java虚拟机的基本结构

jvm它包含以下部分 第一个&#xff1a;类加载系统 类加载子系统&#xff0c;负责类的加载。类加载器有三种类型&#xff1a;引导类加载器、扩展类加载器、应用程序类加载器。 第二个&#xff1a;运行时数据区 包含了程序计数器、Java虚拟机栈、本地方法栈、堆 、方法区。 程…

uniapp引入七鱼客服微信小程序SDK

小程序引入七鱼sdk 1.微信公众平台引入2.代码引入3.在pagesQiyu.vue初始化企业appKey4.跳转打开七鱼客服 1.微信公众平台引入 账号设置->第三方设置->添加插件->搜索 QIYUSDK ->添加 2.代码引入 在分包中引入插件 "subPackages": [{"root":…

手撕算法(定制整理版2)

最长无重复子字符串 class Solution(object):def lengthOfLongestSubstring(self, s):""":type s: str:rtype: int"""if not s:return 0max_len 0tp []for a in s:while a in tp:del tp[0]tp.append(a)if len(tp) > max_len:max_len len(…

数字IC后端培训教程之数字后端项目典型案例分析

今天给大家分享下最近小编帮助学员解决的几个经典数字IC后端项目问题。希望能够对大家的学习和工作有所帮助。 数字IC后端项目典型问题之后端实战项目问题记录&#xff08;2025.04.24&#xff09; 数字IC后端设计实现培训教程&#xff08;整理版&#xff09; Q1: 老师好&…

window 显示驱动开发-将虚拟地址映射到内存段(二)

在将虚拟地址映射到段的一部分之前&#xff0c;视频内存管理器调用显示微型端口驱动程序的 DxgkDdiAcquireSwizzlingRange 函数&#xff0c;以便驱动程序可以设置用于访问可能重排的分配位的光圈。 驱动程序既不能将偏移量更改为访问分配的 PCI 光圈&#xff0c;也不能更改分配…

Termius ssh连接服务器 vim打开的文件无法复制问题

你的问题是&#xff1a; • 在 Termius (macOS) SSH 连接到 VMware Ubuntu&#xff0c;使用 vim 打开 .cpp 文件时&#xff0c;可以复制文本&#xff1b; • 但在 Windows 10 上 SSH 到 VMware 的 Red Hat 6.4 时&#xff0c;复制操作无效。 ⸻ &#x1f3af; 初步分析 复制…

杨校老师项目之基于SSM与JSP的鲜花销售系统-【成品设计含文档】

基于SSMJSP鲜花商城系统 随着电子商务的快速发展&#xff0c;鲜花在线销售已成为一种重要的消费模式。本文设计并实现了一个基于JSP技术的鲜花销售管理系统&#xff0c;采用B/S架构&#xff0c;使用SSM框架进行开发&#xff0c;并结合Maven进行项目依赖管理。系统分为前台用户模…