文内代码全部采用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判断当前可以拿多少水果。
tree | 3 | 3 | 3 | 1 | 2 | 1 | 1 | 2 | 3 | 3 | 4 |
---|---|---|---|---|---|---|---|---|---|---|---|
num | 1 | 2 | 3 | 4 | 2 | 3 | 4 | 5 | 2 | 3 | 3 |
p1 | 0 | 0 | 0 | 0 | 3 | 3 | 3 | 3 | 7 | 7 | 8 |
p2 | 1 | 2 | 3 | 3 | 4 | 4 | 4 | 4 | 8 | 8 | 10 |
newstart | 3 | 4 | 5 | 5 | 7 | 8 | 8 | 10 | |||
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
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% 的用户