当前位置: 首页 > news >正文

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]测试用例

提交结果:

相关文章:

  • 《P1177 【模板】排序》
  • 高质量老年生活:从主动健康管理到预防医学的社会价值
  • 一种安全不泄漏、高效、免费的自动化脚本平台
  • C++学习-入门到精通-【5】类模板array和vector、异常捕获
  • CMA认证对象?CMA评审依据,CMA认证好处
  • PPI-ID: 德克萨斯大学研究团队最新款蛋白-蛋白互作(PPI)预测工具上线
  • Java中医门诊系统源码 中医诊所系统源码
  • Ascend的aclgraph(2)_npu_backend中还有些什么秘密?
  • 数据类型详解(布尔值、整型、浮点型、字符串等)-《Go语言实战指南》
  • jenkins 启动报错
  • 少儿编程机构用的教务系统
  • 集成电路流片随笔26:tinyriscv的三级流水线细则pc
  • Windows 10 无法启动或黑屏的修复指南(适用于更新失败或磁盘故障)
  • ResNet详解
  • 全层微调:解锁预训练模型的无限潜力
  • js-getSelection获取选中内容
  • tcpdump 的用法
  • CDGP重点知识梳理(82个)
  • Auto DOP:让并行执行实现智能调优 | OceanBase 实践
  • 达梦、PostgreSQL数据库讲json解析成临时表(json_table函数的使用)
  • 领证不用户口本,还需哪些材料?补领证件如何操作?七问七答
  • 优秀“博主”在上海杨浦购房最高补贴200万元,有何条件?
  • 西南大学教授、重庆健美运动奠基人之一李启圣逝世
  • 陕西澄城樱桃在上海推介,向长三角消费者发出“甜蜜之邀”
  • 三大交易所多举措支持科创债再扩容,约160亿证券公司科创债有望近期落地
  • 观察|22项达全球最优,世行为上海营商环境“盖章”