在一排树中,第 i 棵树产生 tree[i] 型的水果。
    你可以从你选择的任何树开始,然后重复执行以下步骤:

    1. 把这棵树上的水果放进你的篮子里。如果你做不到,就停下来。
    2. 移动到当前树右侧的下一棵树。如果右边没有树,就停下来。

    请注意,在选择一颗树后,你没有任何选择:你必须执行步骤 1,然后执行步骤 2,然后返回步骤 1,然后执行步骤 2,依此类推,直至停止。

    你有两个篮子,每个篮子可以携带任何数量的水果,但你希望每个篮子只携带一种类型的水果。

    用这个程序你能收集的水果树的最大总量是多少?

    示例 1:

    1. 输入:[1,2,1]
    2. 输出:3
    3. 解释:我们可以收集 [1,2,1]。

    示例 2:

    输入:[0,1,2,2]
    输出:3
    解释:我们可以收集 [1,2,2]
    如果我们从第一棵树开始,我们将只能收集到 [0, 1]。
    

    示例 3:

    输入:[1,2,3,2,2]
    输出:4
    解释:我们可以收集 [2,3,2,2]
    如果我们从第一棵树开始,我们将只能收集到 [1, 2]。
    

    示例 4:

    输入:[3,3,3,1,2,1,1,2,3,3,4]
    输出:5
    解释:我们可以收集 [1,2,1,1,2]
    如果我们从第一棵树或第八棵树开始,我们将只能收集到 4 棵水果树。
    

    提示:

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

    题解:

    时间复杂度是n,空间复杂度是1,两者的最优化才是双指针滑动窗口的精髓

    class Solution {
    public:
        int totalFruit(vector<int>& fruits) {
            //数组中存储的是水果的类型,计算的结果是能够收集的树的数量
            //这里的树也一定是连续的,所以也是指针型的滑动窗口问题
            int slowIndex = 0;
            int res = 0;
            int bask = 0;
            int len = 0;
            //len在for循环里面没有归零重新计算过,是不停更新,用res记录更新过程中的最大值
            int a1,a2; //记录篮子里有哪两种水果
            for(int fastIndex = 0;fastIndex < fruits.size();fastIndex++){
                //篮子为空
                if(bask == 0){
                    a1 = fruits[slowIndex]; //空篮子就标记第一个水果
                    bask++;
                    len++;
                }
                //篮子装了一个
                else if(bask == 1){
                    if(fruits[fastIndex] == a1){ //是已经装过的
                        len++;
                    }
                    else{                        //没有装过的
                        a2 = fruits[fastIndex];
                        bask++;
                        len++;
                        slowIndex = fastIndex;   //左指针换到右指针
                    }
                }
                //篮子装了俩
                else{
                    if(fruits[fastIndex] == a1||fruits[fastIndex] == a2){ //其中之一
                        len++;
                        if(fruits[fastIndex] != fruits[fastIndex - 1]) slowIndex = fastIndex; 
                        //不是两个连续一样的水果则需要更换下一次的指针
                    }
                    else{   //篮子已经装不下了
                        if(len > res) res = len; //更新结果
                        len = fastIndex - slowIndex;
                        bask = 1;    //拿掉前面一个水果,进入下一次循环
                        a1 = fruits[slowIndex]; 
                        fastIndex--;
                    }
                } 
            }
            if(len > res) res = len;
            return res;
    
    
       }
    };