leetcode 904. 水果成篮(优质解法)

代码:

class Solution {
    public int totalFruit(int[] fruits) {
        int length=fruits.length;
        int []fruitNums=new int[length+1];  //用于记录各个种类摘了多少个水果
        int count=0;    //用于记录当前采摘了几种水果
        int sum=0;  //用于记录当前共摘了多少水果
        for(int left=0,right=0;right<fruits.length;right++){
            //将 right 指针指向的数据进窗口
            int in=fruits[right];   //要采摘的水果
            //判断当前采摘的水果是否是之前没有的种类
            if(fruitNums[in]==0){
                count++;
                //判断水果种类是否超过了2
                while (count>2){
                    //将 left 指针指向的数据出窗口
                    int out=fruits[left++];
                    fruitNums[out]--;
                    if(fruitNums[out]==0){
                        count--;
                    }
                }
            }
            fruitNums[in]++;
            sum=Math.max(sum,right-left+1);
        }

        return sum;
    }
}

题解:

        首先我们需要理清题目需求:

        (1).只有 两个 篮子,并且每个篮子只能装 单一类型 的水果,说明只能选两个类型的水果

        (2).可以选择任意一棵树开始采摘,必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 ,每采摘一次,你将会向右移动到下一棵树,并继续采摘,一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。说明必须连续采摘,直到水果类型超过两种为止

        通过连续二字,我们很容易想到,该题目需要我们找到一个符合要求的子数组,首先子数组中的数字种类不能超过 2 ,其次我们要找到符合条件的最长子数组,取得他的长度

        我们很容易想到的暴力解法就是,遍历出所有的子数组,找到数字种类不能超过 2并且长度最长的那一个

        对于查找子数组的相关问题,通常我们会想到采用滑动窗口的方法来解决,用示例3来说明fruits = [1,2,3,2,2]

        首先需要遍历找出符合条件的子数组,让 L 和 R 指针指向下标为 0 的位置,L 和 R 指针之间便是我们当前要讨论的子数组,我们用一个哈希表 fruitNums 来记录篮子里已经装的水果种类和数量,用 count 来记录当前篮子里已经有的水果种类,当 R 指针指向 1 时,我们就需要在哈希表中添加 key =1,value=1 的信息,代表篮子中有 1 个种类为 1 的水果,由于之前哈希表中没有种类 1水果的相关信息,代表篮子中的水果种类增加 1 ,此时 count = 1,记录当前的水果数量 1

1        2        3        2        2

L

R

        让 R 指针向右移动,再添加一个水果到篮子中,在哈希表中添加 key =2,value=1 的信息,由于之前哈希表中没有种类 2 水果的相关信息,代表篮子中的水果种类增加 1 ,此时 count = 2,记录当前的水果数量 2

1        2        3        2        2

L

          R        

        让 R 指针向右移动,再添加一个水果到篮子中,在哈希表中添加 key =3,value=1 的信息,由于之前哈希表中没有种类 3 水果的相关信息,代表篮子中的水果种类增加 1 ,此时 count = 3 > 2,两个篮子装不下了,代表以 L 指针为首的子数组讨论完毕,现在让 L 指针向右移动

1        2        3        2        2

L

                    R  

        L 指针向右移动后,哈希表中的 key =1 对应的 value 值减 1,value = 0,代表篮子中少了一种水果,count减 1 ,为 2,记录当前的水果数量 2 ,这里就存在一个问题,当 L 指针向右移动,是否需要 R 指针回到 L 指针所在的位置,从头遍历子数组?答案是不需要, 因为此时 L 指针和 R 指针之间(不包括 R 指针)的水果种类肯定是小于等于 2 的,只有加上 R 指针指向的水果,水果种类才可以多于 2 ,即使 R 指针回到 L 指针所在的位置,后面还是会移动到当前位置 

1        2        3        2        2

          L       

                    R  

        后面就一直循环上述操作即可

        

        

        

Guess you like

Origin blog.csdn.net/q322359/article/details/134929985