【代码随想录刷题记录】LeetCode904水果成篮

发布于:2024-05-02 ⋅ 阅读:(30) ⋅ 点赞:(0)

题目地址

1. 思路

这个题拿到手以后我没什么思路,看了官方的题解以后,才明白是怎么回事,首先,它有两个果篮,但是只能限制最多装两类水果,人是从果树那个数组从下标为0的果树走到数组最后的果树,要想摘的果树最多,就是求它的最大连续子数组,相当于之前【代码随想录刷题记录】LeetCode209长度最小的子数组的条件魔改一下,不再求minlen=min(minlen, right - left + 1),而是求max_len = max(max_len , right -left + 1),使用哈希表来作为水果篮子,键为水果类别编号,值为该类别的水果数量,而且for循环中的while循环条件也变一下,即哈希表的长度如果大于2(即两个水果篮子只能装下两个类别的水果,突然来了个第三类别的水果,装不下了),则让哈希表中fruits[left]这个键对应的值减少,并让left指针右移,直到哈希表中有两个类的水果。这里面的哈希表用的是C++ STL的unordered_map,我没有想到更好的实现方式,我只学会了官方的题解。

2. 代码实现

我的注释尽量写的明确一点,代码如下:

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        int n = fruits.size(); //数组长度
        int left = 0;  // 左指针
        unordered_map<int, int> cnt;  // 哈希表,用于统计每种水果的数量,键为水果类别编号,值为该类别的水果数量
        int max_len = INT32_MIN;  // 记录最大连续子数组的长度
        //遍历果树
        for(int right = 0;right < n;right++)
        {
            // 右指针遇到下一棵果树,就让哈希表中对应类别的果树数量自增
            cnt[fruits[right]]++;
            // 如果哈希表中出现三个类别的果树(即我们多摘了一个类),则将fruits[left]从哈希表中移除
            // 然后再将left向右移动
            // 一直到不满足哈希表中存在超过两个类别的果树为止,不满足条件,可以继续搜索新解
            while(cnt.size() > 2)
            {
                auto it = cnt.find(fruits[left]);  // 获取left指针指向的果树的果子种类对应的个数,find成员函数返回的是一个迭代器(iterator)类型
                (it->second)--;// it->second 就是迭代器 it 所指向的键值对中的值,也就是left指针对应的类的水果的数量
                // 如果该水果的数量减少到0,则从哈希表中删除该水果  
                if (it->second == 0) {  
                    cnt.erase(it);  
                }
                left++; //左指针向右移动
            }
            max_len = max(max_len, right - left + 1); // 返回最大连续子数组的长度,只有最大连续子数组的时候,限制两个类别的情况下,摘的果树才是最多的。
        }
        return max_len;
    }
};