题目描述:代码随想录-数组-5-滑动窗口

中等

904. 水果成篮

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

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

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

给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。

思路:

1、直接暴力解

类似双指针的滑动窗口,定义左指针(慢,i)和右指针(快,j),定义一个sum 是记录这次能装多少个水果,定义type1,type2记录两种水果的种类。慢指针指向装的第一个水果(顺便定义了type1 = fruits[i]),定义 k 代表第二种水果第一次出现的位置(顺便定义了type2 = fruits[k]),快指针从0开始循环,往右移动的过程中,每次移动需要判断 fruits[j] 是否等于type1或type2中的一个,如果等于,sum++ ;如果不等于,就需要重置,即挪动 i 指针,第一种方法是直接 i++,sum--, 太费时间;第二种方法是直接把 i 移到 第二种水果第一次出现的位置即 k ,此时 sum也需要更新为 sum - (k - i) 。应该就差不多了。

class Solution {
public:int totalFruit(vector<int>& fruits) {//符合只有两个不同数的,最长子序列,滑动窗口 15:22 (5月底没想完)//7.2 继续想20:00开始,想到21.30也没AC 纯傻逼;//7.4下午3.10又开始debug,暴力解应该没问题了,就是超出时间限制,o(n^2)//7.4 想更新i-----16.44通过了,注意,滑动窗口i跳了的话,Sum也得跳int i = 0;int sum = 1;int type1 = -1; int type2 = -1;int result = 0;//边界情况,输入[0]if(fruits.size() == 1) return 1;//快指针在外循环for (int j = 1; j < fruits.size(); j++){//定义type1type1 = fruits[i];// if((fruits[j] != type1) && (type2 == -1)) type2 = fruits[j];  //初值赋的不对,这样会跳过中间某些数如 [3,3,3,1,2,1,1,2,3,3,4]//定义type2 出现在 k处int k = i;  //k的位置也很重要,必须在这个外面if((fruits[j] != type1) && (type2 == -1)){for(;k<=j;k++){if(fruits[k]!=fruits[i]){type2 = fruits[k];break;}}    }if((fruits[j] == type1) || (fruits[j] == type2)){sum++;if(sum > result) {result = sum; // result = j - i + 1; //都可以//cout<<"result (in j = "<<j<<" ) :"<<reuslt<<endl;}}else{// 重置// way1 -- 暴力解 i每次只挪一下,way1在leetcode会超出时间// i++;// sum--;  //一定是sum--!!!因为i往右边移的同时,Sum-1即可//way2 -- 滑动窗口 想直接跳isum = sum - (k - i);  //sum得在i前更新i = k;j--; // 一定要!!!不论way1还是way2都要保证j不动,所以先减,再下一次循环再加type2 = -1;}}return result;}
};

白板输出:

class Solution904 {
public:int totalFruit(vector<int>& fruits) {//符合只有两个不同数的,最长子序列,滑动窗口 15:22 (5月底没想完)//7.2 继续想20:00开始int i = 0;int sum = 1;int type1 = -1;int type2 = -1;int result = 0;int k = -1;//边界情况,输入[0]if(fruits.size() == 1) return 1;//快指针在外循环for (int j = 1; j < fruits.size(); j++){cout<<"j: "<<j<<endl;//定义type1type1 = fruits[i];//if((fruits[j] != type1)&& (type2 == -1)) type2 = fruits[j];//初值赋的不对,这样会跳过中间某些数如 [3,3,3,1,2,1,1,2,3,3,4]//定义type2 出现在 k处if((fruits[j] != type1) && (type2 == -1)){k = i;for(;k<=j;k++){if(fruits[k] != fruits[i]){type2 = fruits[k];break;}}}cout << "type2出现的位置k :" << k <<endl;//如果j位置的水果与type1 type2相同,sum++if((fruits[j] == type1)||(fruits[j] == type2)){sum++;if(sum > result) {result = sum;    //way1//result = j - i + 1;cout<<"type1,2: " << type1 << " " <<type2<<endl;cout<<"result (in i = " << i <<" j = "<<j<<" ) :"<<result<<endl;}}else{//                // way1
//                cout << "i = " << i << endl;
//                i++;
//                j--; // 一定要!!!!!
//                sum--;// way2 直接跳i, i更新,sum也得更新// i = j - 1;//绝对不对sum = sum - (k - i);  //sum得在i前更新i = k;j--;type2 = -1;cout << "i = " << i << endl;cout<<"重置"<<endl;}}return result;}
};int main(){Solution904 sol;int arr1[3] = {1,2,1};vector<int> fruits1 ;for(int i = 0;i<3;i++){fruits1.push_back(arr1[i]);cout<<fruits1[i]<<"";}cout << endl;cout << "示例输出:" <<sol.totalFruit(fruits1) <<endl;cout << endl;int arr2[4] = {0,1,2,2};vector<int> fruits2 ;for(int i = 0;i<4;i++){fruits2.push_back(arr2[i]);cout << fruits2[i]<<" ";}cout << endl;cout << "示例输出:" <<sol.totalFruit(fruits2) <<endl;cout << endl;int arr41[11] = {3,3,3,1,2,1,1,2,3,3,4};vector<int> fruits41 ;for(int i = 0;i<11;i++){fruits41.push_back(arr41[i]);cout << fruits41[i]<<" ";}cout << endl;cout << "示例输出:" <<sol.totalFruit(fruits41) <<endl;cout << endl;int arr68[1] = {0};vector<int> fruits68 ;fruits68.push_back(arr68[0]);cout << endl;cout << "示例输出:" <<sol.totalFruit(fruits68) <<endl;cout << endl;int arr3[2] = {0,1};vector<int> fruits3 ;for(int i = 0;i<2;i++){fruits3.push_back(arr3[i]);cout << fruits3[i]<<" ";}cout << endl;cout << "示例输出:" <<sol.totalFruit(fruits3) <<endl;cout << endl;int arr69[7] = {0,1,6,6,4,4,6};vector<int> fruits69 ;for(int i = 0;i<7;i++){fruits69.push_back(arr69[i]);cout << fruits69[i]<<" ";}cout << endl;cout << "示例输出:" <<sol.totalFruit(fruits69) <<endl;cout << endl;int arr80[8] = {4,1,1,1,3,1,7,5};vector<int> fruits80 ;for(int i = 0;i<8;i++){fruits80.push_back(arr80[i]);cout << fruits80[i]<<" ";}cout << endl;cout << "示例输出:" <<sol.totalFruit(fruits80) <<endl;cout << endl;return 0;
}

2、其他解法

来自leetcode评论区

(1)上面暴力解的改进版,在循环 j 时就顺便把第二种水果第一次出现的位置记录下来

力扣 C++ 双指针,可以用一个单独指针指向left下一次跳转的位置,也可以先left=right-1,再进行回退

class Solution {public:int totalFruit(vector<int>& fruits) {int left = 0, right = 0; // 双指针法,自己想到的!int firstSort = -1, secondSort = -1;int maxCount = 0; // 可以收集的最大数目int thirdBefore = 0; // thirdBefore指向第三种果树的前一种果树的第一棵firstSort = fruits[left]; for (right = 0; right < fruits.size(); right++) {if (fruits[right] != firstSort && secondSort == -1) {secondSort = fruits[right];}if (fruits[right] == firstSort || fruits[right] == secondSort) {maxCount = right - left + 1 > maxCount ? right - left + 1 : maxCount;} else {left = thirdBefore; // 移动慢指针firstSort = fruits[left];secondSort = fruits[right];}if (right > 0 && fruits[right] != fruits[right-1]) {thirdBefore = right;}}return maxCount;
}作者:meirikele
链接:https://leetcode.cn/problems/fruit-into-baskets/solution/by-meirikele-qpqu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

(2)这道题是最大覆盖字串,和最小覆盖子串的区别

力扣

leetcode 904 水果成篮相关推荐

  1. LeetCode 904. 水果成篮

    904. 水果成篮 题目:你正在探访一家农场,农场从左到右种植了一排果树.这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 . 你想要尽可能多地收集水果 ...

  2. LeetCode 904. 水果成篮【fruit-into-baskets】

    904. 水果成篮 题目详情 题目传送门:904. 水果成篮 在一排树中,第 i 棵树产生 tree[i] 型的水果. 你可以从你选择的任何树开始,然后重复执行以下步骤: 把这棵树上的水果放进你的篮子 ...

  3. 力扣(LeetCode)904. 水果成篮(C语言)

    一.环境说明 本文是 LeetCode 904题 : 水果成篮,使用c语言实现 滑动窗口+哈希集合. 测试环境:Visual Studio 2019 二.代码展示 //滑动窗口+哈希表,一次遍历O(n ...

  4. LeetCode 904. 水果成篮(滑动窗口)

    1. 题目 在一排树中,第 i 棵树产生 tree[i] 型的水果. 你可以从你选择的任何树开始,然后重复执行以下步骤: 把这棵树上的水果放进你的篮子里.如果你做不到,就停下来. 移动到当前树右侧的下 ...

  5. leetcode 904:水果成篮(滑动窗口)

    一:题目 二:思路 1.用两个篮子装进两个数,后面只能装入这两个相同的数,并统计个数;如果遇到其他数,则重新开始计数, 这里的重新开始计数指的是在去除第一个篮子中所装进的数 2.滑动窗口来做 滑动窗口 ...

  6. 2022-7-8 Leetcode 904.水果成篮

    错误的代码: class Solution {public:int totalFruit(vector<int>& fruits) {int start = 0;int end = ...

  7. LeetCode每日一题——904. 水果成篮

    LeetCode每日一题系列 题目:904. 水果成篮 难度:普通 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 你正在探访一家农场,农场从左到右种植了一排果树.这些树用一个整 ...

  8. leetcode 题解 904.水果成篮(Typescript)

    /* * @lc app=leetcode.cn id=904 lang=typescript * * [904] 水果成篮(实质为求最大两元素连续子串) */ //滑动窗口 // @lc code= ...

  9. leetcode:904. 水果成篮

    题目来源 leetcode:904. 水果成篮 题目描述 题目解析 题意 题意从任意位置开始,若最多只能收集两种水果,问最多能收集多少个水果. 这道题目可以理解为求只包含两种元素的最长连续子序列,和l ...

  10. 【042】904. 水果成篮[滑动窗口]

    你正在探访一家农场,农场从左到右种植了一排果树.这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 . 你想要尽可能多地收集水果.然而,农场的主人设定了一 ...

最新文章

  1. monty python life of brian-电影Life of Brian 万世魔星
  2. ajax mysql项目 react_React视频教程来啦,每周末都有前端视频教程学
  3. PCB学习第一节内容整理
  4. nand ubi -4 kernel和mtd
  5. python笔记之利用BeautifulSoup爬取糗事百科首页段子
  6. 初一模拟赛总结(3.16)
  7. CSS3 实用技巧:制作三角形
  8. 公众平台模板消息所在行业_第三方工具微信公众号模板消息群发如何操作?
  9. 转转钓鱼php,最新转转钓鱼源码程序网站微信:mm88wk 最新转转源码 - 下载 - 搜珍网...
  10. Datatables + Bootstrap
  11. 错误摘要 HTTP 错误 403.14 - Forbidden Web 服务器被配置为不列出此目录的内容。
  12. html帧动画效果,利用css3-animation实现逐帧动画效果
  13. 0. SQL Server监控清单
  14. 计算机名ip自动配置文件,[已解决]批处理如何根据网卡MAC地址自动设置IP和计算机名?...
  15. Cadence Allegro针对Shape进行Vertex推挤拉伸操作方法图文教程
  16. wamp mysql使用方法_wamp使用方法【总】
  17. 【VTM10.0】量化之RDOQ技术
  18. 一行代码回显 LayUI表单数据回显 下拉列表select回显
  19. Linux中select IO复用机制
  20. linux awk统计文本单词,shell统计文本中单词的出现次数

热门文章

  1. java库的使用--Failsafe
  2. php上位机,OV7670摄像头上位机软件源码
  3. 听北大公开课庄明科老师《大学生职业素养提升》第一集:《自我效能感》的笔记
  4. poj 3268 Silver Cow Party(最短路dijkstra)
  5. 【计算机网络】光纤传输的全反射
  6. 基于XC7K325T光纤传输的PCIE光纤卡、2路光纤的资料
  7. prometheus中step或resolution的含义
  8. latex入门(五) 插入表格
  9. 苹果电脑的文件怎么复制到移动硬盘,macbook文件怎么拷贝到移动硬盘
  10. 关键词策略 —关键词选择