Java&LeetCode 初入门——904. 水果成篮

Java&LeetCode 初入门——904. 水果成篮

文内代码全部采用JAVA语言。

题目

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

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

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

你有两个篮子,每个篮子可以携带任何数量的水果,但你希望每个篮子只携带一种类型的水果。
用这个程序你能收集的水果总量是多少?

测试用例

示例 1:

输入:[1,2,1]
输出: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 个水果。

个人解法

首先肯定想实现题目中的两个步骤,然后从第0棵树开始查录,直到遍历完所有树之后,找最大值。
但是很不幸,方法超时了。

于是想用第二种方法,有一点接近与动态规划,但是不太一样。
首先建立一个和tree相同大小的数组num,用来存放当前能拿到的最大的水果数量。两个指针p1,p2记录第一次出现的两个不同种类的水果在tree中的位置,newstart记录,当发现第三种水果的时候,应该从哪一个位置开始更新。

举个例子:tree=[3,3,3,1,2,1,1,2,3,3,4];
第一种水果的位置p1=0;下面寻找第二种水果的位置p2,while循环找到第二种水果在4位置,并在循环内更新可以拿到的水果数量,由于目前只找到两种,所以每次加1即可。并更新newstart位置为p2;
下面开始从i=p2+1位置,进行遍历。如果i位置的水果是p1和p2中的一种,那么可拿水果数量num[i]=num[i-1]+1;如果i位置的水果和i-1位置的水果不同种类,那么更新newstart=i;如果当前水果是新品种,那么根据newstart判断当前可以拿多少水果。

tree33312112334
num12342345233
p100003333778
p2123344448810
newstart345578810
index012345678910

在这里插入图片描述

class Solution {
    public int totalFruit(int[] tree) {
        int p1=0;
        if(tree.length<=2){
            return tree.length;
        }
        int [] num=new int [tree.length];
        num[0]=1;
        int p2=1;
        while ( tree[p2]==tree[p1]){
            num[p2]=num[p2-1]+1;
            p2++;
            if(p2==tree.length){
                return num[p2-1];
            }
        }
        num[p2]=num[p2-1]+1;
        int max=num[p2];
        int nextstart=p2;
        for(int i=p2+1;i<tree.length;i++){
            if(tree[i]==tree[p1] || tree[i]==tree[p2]){
                if(tree[i]!=tree[i-1]){
                    nextstart=i;
                }
                num[i]=num[i-1]+1;
                max=Math.max(max,num[i]);
            }else{

                if(p1<p2){
                    p1=i;
                    p2=nextstart;
                }else{
                    p2=i;
                    p1=nextstart;
                }
                nextstart=i;
                num[i]=Math.max(p1,p2)-Math.min(p1,p2)+1;
            }
        }
        return max;
    }
}

执行用时 : 17 ms, 在Fruit Into Baskets的Java提交中击败了79.65% 的用户
内存消耗 : 67.2 MB, 在Fruit Into Baskets的Java提交中击败了48.33% 的用户

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值