iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++实现LeetCode(904.水果装入果篮)
  • 351
分享到

C++实现LeetCode(904.水果装入果篮)

2024-04-02 19:04:59 351人浏览 泡泡鱼
摘要

[LeetCode] 904. Fruit Into Baskets 水果装入果篮 In a row of trees, the `i`-th tree prod

[LeetCode] 904. Fruit Into Baskets 水果装入果篮

In a row of trees, the `i`-th tree produces fruit with type `tree[i]`.

You start at any tree of your choice, then repeatedly perfORM the following steps:

  1. Add one piece of fruit from this tree to your baskets.  If you cannot, stop.
  2. Move to the next tree to the right of the current tree.  If there is no tree to the right, stop.

Note that you do not have any choice after the initial choice of starting tree: you must perform step 1, then step 2, then back to step 1, then step 2, and so on until you stop.

You have two baskets, and each basket can carry any quantity of fruit, but you want each basket to only carry one type of fruit each.

What is the total amount of fruit you can collect with this procedure?

Example 1:

Input: [1,2,1]
Output: 3
Explanation: We can collect [1,2,1].

Example 2:

Input: [0,1,2,2]
Output: 3
Explanation: We can collect [1,2,2]. If we started at the first tree, we would only collect [0, 1]. 

Example 3:

Input: [1,2,3,2,2]
Output: 4
Explanation: We can collect [2,3,2,2]. If we started at the first tree, we would only collect [1, 2]. 

Example 4:

Input: [3,3,3,1,2,1,1,2,3,3,4]
Output: 5 
Explanation: We can collect [1,2,1,1,2]. If we started at the first tree or the eighth tree, we would only collect 4 fruits. 

Note:

  1. 1 <= tree.length <= 40000
  2. 0 <= tree[i] < tree.length

这道题说是给了我们一排树,每棵树产的水果种类是 tree[i],说是现在有两种操作,第一种是将当前树的水果加入果篮中,若不能加则停止;第二种是移动到下一个树,若没有下一棵树,则停止。现在我们有两个果篮,可以从任意一个树的位置开始,但是必须按顺序执行操作一和二,问我们最多能收集多少个水果。说实话这道题的题目描述确实不太清晰,博主看了很多遍才明白意思,论坛上也有很多吐槽的帖子,但实际上这道题的本质就是从任意位置开始,若最多只能收集两种水果,问最多能收集多少个水果。那么再进一步提取,其实就是最多有两个不同字符的最长子串的长度,跟之前那道 [Longest Substring with At Most Two Distinct Characters](Http://www.cnblogs.com/grandyang/p/5185561.html) 一模一样,只不过换了一个背景,代码基本都可以直接使用的,博主感觉这样出题有点不太好吧,完全重复了。之前那题的四种解法这里完全都可以使用,先来看第一种,使用一个 HashMap 来记录每个水果出现次数,当 HashMap 中当映射数量超过两个的时候,我们需要删掉一个映射,做法是滑动窗口的左边界 start 的水果映射值减1,若此时减到0了,则删除这个映射,否则左边界右移一位。当映射数量回到两个的时候,用当前窗口的大小来更新结果 res 即可,参见代码如下:
解法一:


class Solution {
public:
    int totalFruit(vector<int>& tree) {
        int res = 0, start = 0, n = tree.size();
        unordered_map<int, int> fruitCnt;
        for (int i = 0; i < n; ++i) {
            ++fruitCnt[tree[i]];
            while (fruitCnt.size() > 2) {
                if (--fruitCnt[tree[start]] == 0) {
                    fruitCnt.erase(tree[start]);
                }
                ++start;
            }
            res = max(res, i - start + 1);
        }
        return res;
    }
};

我们除了用 HashMap 来映射字符出现的个数,我们还可以映射每个数字最新的坐标,比如题目中的例子 [0,1,2,2],遇到第一个0,映射其坐标0,遇到1,映射其坐标1,当遇到2时,映射其坐标2,每次我们都判断当前 HashMap 中的映射数,如果大于2的时候,那么需要删掉一个映射,我们还是从 start=0 时开始向右找,看每个字符在 HashMap 中的映射值是否等于当前坐标 start,比如0,HashMap 此时映射值为0,等于 left 的0,那么我们把0删掉,start 自增1,再更新结果,以此类推直至遍历完整个数组,参见代码如下:
解法二:


class Solution {
public:
    int totalFruit(vector<int>& tree) {
        int res = 0, start = 0, n = tree.size();
        unordered_map<int, int> fruitPos;
        for (int i = 0; i < n; ++i) {
            fruitPos[tree[i]] = i;
            while (fruitPos.size() > 2) {
                if (fruitPos[tree[start]] == start) {
                    fruitPos.erase(tree[start]);
                }
                ++start;
            }
            res = max(res, i - start + 1);
        }
        return res;
    }
};

后来又在网上看到了一种解法,这种解法是维护一个滑动窗口 sliding window,指针 left 指向起始位置,right 指向 window 的最后一个位置,用于定位 left 的下一个跳转位置,思路如下:

  • 若当前字符和前一个字符相同,继续循环。

  • 若不同,看当前字符和 right 指的字符是否相同:

    • 若相同,left 不变,右边跳到 i - 1。

    • 若不同,更新结果,left 变为 right+1,right 变为 i - 1。

最后需要注意在循环结束后,我们还要比较结果 res 和 n - left 的大小,返回大的,这是由于如果数组是 [5,3,5,2,1,1,1],那么当 left=3 时,i=5,6 的时候,都是继续循环,当i加到7时,跳出了循环,而此时正确答案应为 [2,1,1,1] 这4个数字,而我们的结果 res 只更新到了 [5,3,5] 这3个数字,所以我们最后要判断 n - left 和结果 res 的大小。

另外需要说明的是这种解法仅适用于于不同字符数为2个的情况,如果为k个的话,还是需要用上面两种解法。

解法三:


class Solution {
public:
    int totalFruit(vector<int>& tree) {
        int res = 0, left = 0, right = -1, n = tree.size();
        for (int i = 1; i < n; ++i) {
            if (tree[i] == tree[i - 1]) continue;
            if (right >= 0 && tree[right] != tree[i]) {
                res = max(res, i - left);
                left = right + 1;
            }
            right = i - 1;
        }
        return max(n - left, res);
    }
};

还有一种不使用 HashMap 的解法,这里我们使用若干个变量,其中 cur 为当前最长子数组的长度,a和b为当前候选的两个不同的水果种类,cntB 为水果b的连续个数。我们遍历所有数字,假如遇到的水果种类是a和b中的任意一个,那么 cur 可以自增1,否则 cntB 自增1,因为若是新水果种类的话,默认已经将a种类淘汰了,此时候选水果由类型b和这个新类型水果构成,所以当前长度是 cntB+1。然后再来更新 cntB,假如当前水果种类是b的话,cntB 自增1,否则重置为1,因为 cntB 统计的就是水果种类b的连续个数。然后再来判断,若当前种类不是b,则此时a赋值为b, b赋值为新种类。最后不要忘了用 cur 来更新结果 res,参见代码如下:
解法四:


class Solution {
public:
    int totalFruit(vector<int>& tree) {
        int res = 0, cur = 0, cntB = 0, a = 0, b = 0;
        for (int fruit : tree) {
            cur = (fruit == a || fruit == b) ? cur + 1 : cntB + 1;
            cntB = (fruit == b) ? cntB + 1 : 1;
            if (b != fruit) {
                a = b; b = fruit;
            }
            res = max(res, cur);
        }
        return res;
    }
};

GitHub 同步地址:

https://github.com/grandyang/leetcode/issues/904

参考资料:

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

https://leetcode.com/problems/fruit-into-baskets/discuss/170740/Sliding-Window-for-K-Elements

https://leetcode.com/problems/fruit-into-baskets/discuss/170745/Problem%3A-Longest-Subarray-With-2-Elements

https://leetcode.com/problems/fruit-into-baskets/discuss/170808/Java-Longest-Subarray-with-atmost-2-Distinct-elements

到此这篇关于c++实现LeetCode(904.水果装入果篮)的文章就介绍到这了,更多相关C++实现水果装入果篮内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++实现LeetCode(904.水果装入果篮)

本文链接: https://www.lsjlt.com/news/131526.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++实现LeetCode(904.水果装入果篮)
    [LeetCode] 904. Fruit Into Baskets 水果装入果篮 In a row of trees, the `i`-th tree prod...
    99+
    2024-04-02
  • C++怎么实现水果装入果篮问题
    这篇文章主要介绍“C++怎么实现水果装入果篮问题”,在日常操作中,相信很多人在C++怎么实现水果装入果篮问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++怎么实现水果装入果篮问题”的疑惑有所帮助!接下来...
    99+
    2023-06-20
  • Java C++题解leetcode904水果成篮
    目录题目要求阅读理解思路:滑动窗口Java数组哈希表C++数组哈希表总结题目要求 阅读理解 读完题的我be like: 去看了遍英文版就懂了,题目中的种类【type】不是种类数&...
    99+
    2022-11-13
    Java C++ 题解水果成篮 Java C++ LeetCode
  • C++实现LeetCode(11.装最多水的容器)
    [LeetCode] 11. Container With Most Water 装最多水的容器 Given n non-negative integers...
    99+
    2024-04-02
  • C++实现LeetCode(135.分糖果问题)
    [LeetCode] 135.Candy 分糖果问题 There are N children standing in a line. Each child is...
    99+
    2024-04-02
  • C++实现LeetCode(42.收集雨水)
    [LeetCode] 42. Trapping Rain Water 收集雨水 Given n non-negative integers representin...
    99+
    2024-04-02
  • vue轻松实现水印效果
    前言: vue项目中使用水印效果,可指定容器 效果图: 1、不指定容器 2、指定容器 实现方法: 1、新建一个配置文件 watermark.js ,可放util,也可放别的地方 ...
    99+
    2024-04-02
  • Android如何实现水波纹效果
    这篇文章主要为大家展示了“Android如何实现水波纹效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Android如何实现水波纹效果”这篇文章吧。效果图attrs.xml自定义属性 ...
    99+
    2023-06-29
  • Android实现水波纹效果实例代码
    效果图 attrs.xml 自定义属性 <declare-styleable name="RippleAnimationView"> <attr...
    99+
    2024-04-02
  • C++实现LeetCode(57.插入区间)
    [LeetCode] 57. Insert Interval 插入区间 Given a set of non-overlapping intervals, ins...
    99+
    2024-04-02
  • CSS如何实现波动水球效果
    这篇文章将为大家详细讲解有关CSS如何实现波动水球效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。今天学习到了一个新的css特效,波动水球效果,也是非常的好看HTML:<!DOCTYPE ...
    99+
    2023-06-08
  • Vue怎么实现加水波纹效果
    本篇内容主要讲解“Vue怎么实现加水波纹效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue怎么实现加水波纹效果”吧!自定义指令指令的作用言简意赅,就是操作底层dom当然vue自身有非常强大...
    99+
    2023-06-29
  • vue实现页面添加水印效果
    最近在做项目的时候要求给页面加上水印效果,废话不多说直接上代码: export function watermark(settings) { debugger; //默认...
    99+
    2024-04-02
  • Echarts.js实现水滴球和海洋效果
    一、水滴球 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
    99+
    2024-04-02
  • PythonPygame实战之水果忍者游戏的实现
    目录一、准备中1.0 游戏规则1.1 游戏图片素材(可修改)1.2 游戏字体素材(可修改)二、环境安装三、开始敲代码3.0 设置界面玩家生命值等3.1 导入模块3.2 界面背景、字体...
    99+
    2024-04-02
  • Android自定义View实现水波纹效果
    介绍:水波纹散开效果的控件在 App 里面还是比较常见的,例如 网易云音乐歌曲识别,附近搜索场景。看下实现的效果:实现思路: 先将最大圆半径与最小圆半径间距分成几等份,从内到外,Paint 透明度依次递减,绘制出同心圆,然后不断的改变这些同...
    99+
    2023-05-30
    android view 水波纹
  • Python Pygame如何实现水果忍者游戏
    这篇文章给大家分享的是有关Python Pygame如何实现水果忍者游戏的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、准备中1.0 游戏规则Python版本的水果忍者小编初始化设置是玩家3条生命值,...
    99+
    2023-06-29
  • 怎么用JS实现覆盖水印效果
    这篇“怎么用JS实现覆盖水印效果”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么用JS实现覆盖水印效果”文章吧。一、效果处...
    99+
    2023-07-05
  • C#实现日历效果
    本文实例为大家分享了C#实现日历效果的具体代码,供大家参考,具体内容如下 展示: 主要代码: public partial class calendar : Form     {...
    99+
    2024-04-02
  • C#/VB.NET实现在Word中插入水印
    目录前言安装在 Word 文档中插入文本水印在 Word 文档中插入图片水印前言 水印是指在 Word 文档的背景中以淡色或灰色显示的文本或图像。它们可用于声明文档的机密性、版权或其...
    99+
    2022-11-13
    C# Word 插入水印  VB.NET实现 Word 插入水印 
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作