水果成篮

目录

一:题目链接

二:题目思路

方法一:

方法二:

三:代码实现


一:题目链接

        题目给出的数组元素大小是水果的种类,再把题目理解综合起来就是在给定的水果序列中,找出最多包含 2 种水果的最长连续子序列的长度

二:题目思路

方法一:

        首先,我们可以通过暴力枚举 + 双指针 +  a 记录当前水果的种类 的方式,先定义指针 left 和 right 在数组起始的位置,left 先固定,right 往后走,遇到不同元素大小时 a++,遇到相同元素大小时不用管,直到 a == 3 的时候,记录当前子数组序列长度,left 再 往后走,right 回到 left 的位置继续上述流程,直到 left 到达数组末尾。返回得到最大的子数组长度即可。

        对于上述的算法,我们可以优化一下。

方法二:

        可以使用哈希表来记录当前水果的种类和数量,但是题目给出的 水果种类 数据范围 不超过 10^5 ,所以我们也可以创建一个数组 f 模拟哈希表,数组下标表示水果种类,下标对应的元素大小表示该种类水果的数量。(亲测后者方法通过时长比前者短)。 再定义一个 kinds 记录当前篮子含有的水果种类,len 记录采摘水果的数量,定义指针 left 和 right 在数组起始的位置。( fruits 是题目给出的水果数组)。

        首先,left 先固定,right 往后走,如果当前的 f [ fruits[ right ] ] == 0,证明当前篮子里还没有这种类型的水果,此时 kinds ++,并且 f [ fruits[ right ] ] ++,len 不断更新采摘水果的数量,right 不断重复此操作。直到 kinds == 3。如图:

        现在,就要移动 left 了,应该怎么移动呢?答案是一直移动直到 kinds == 2 时停止,此时 left 位置是:

        因为 right 当前的位置(包含right)已经超过 2 种水果了,那么,必须保证 right 前面只有一种水果 left 才能移动。所以,此时 right 继续重复上述的移动过程,直到 right 走到水果数组 fruits 结尾位置结束。返回过程中 len 记录的最大的长度。

三:代码实现

        //使用数组下标模拟水果种类,元素大小表示该种类水果的数量
        int n = fruits.length;
        int[] f = new int[n];

        //记录当前水果种类
        int kinds = 0;

        //记录采摘水果的数量
        int len = 0;

        int left = 0;
        for(int right = 0;right < n;right++) {

            //当前水果的种类
            int k = fruits[right];
            if(f[k] == 0) {
                kinds++;
            }
            f[k]++;  //进窗口

            while(kinds > 2) {
                //left 位置的水果种类
                int a = fruits[left];

                f[a]--;
                if(f[a] == 0) {
                    kinds--;
                }
                left++;
            }

            //更新采摘水果数量
            len = Math.max(len,right - left + 1);
        }

        return len;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值