[C++] 水果成篮-双指针

0. 题干

leetcode 904:
在一排树中,第 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 个水果。

提示:

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

注意这里题目稍微有点难理解,比如那个[0,1,2,2]的例子,tree[0]=0、tree[1]=1、tree[2]=2、tree[3]=2,因为只有两个篮子,一个篮子只能存一种水果,所以要么存0、1;要么存1、2、2;题干说的两个步骤,停下来的意思是程序直接结束了

1. 代码如下,写了很详细的注释

class Solution{
public:
	int totalFruit(vector<int>& tree) {
		int left=0,mid=0,right=0;
		int len=tree.size();

		int sum=0; //统计最终的返回值
	
		if (len<2)   //数组长度小于2,还解个锤子,直接返回数组长度
			return len;
		
		for (; right<len-1; right++) // 找到第二种树的位置
			if( tree[right]!= tree[right+1] ) //此时的right+1值即为第二种树开始位置
			break;
		
		mid= ++right; //此时的mid存储第二种树的位置
		              //运行之后,right的值默认为第二种树开始的位置
		
		
		//以下for循环为重点处理
		
		for (; right < len; right++){
		
				if ( tree[right]!= tree[mid] && tree[right]!= tree[left] ) {
				//找到第三种树
					sum = max(sum, right-left); //每次运行之后的right即为下一种树的开头,
					//所以直接减去left即可.
					
					mid = right; //存储此时第三种树的位置
					
					left= right -1; //既然之前找到了第三种树,此时减一即为第二种树的位置
					
					while ( tree[left] == tree[left-1] )
						//通过这种方式找到前面一种树第一次出现的位置
						left--;
				}

		}
		
		right--;  //for循环运行之后,right=len,减一避免下面数组越界
		
		if (left==0)
			return len; //如果left=0,即,left[2]=left[1],left[1]=left[0]等. 
		                //表明树的种类一定是小于三种的,因为如果树的种类大于三种,
						//由于while ( tree[left] == tree[left-1] )
						//left一定会卡在中间某个位置,不会在0
		if (tree[right] == tree[mid] || tree[right] == tree[left])
		//若数组的最后一位不是新的树,即不经过重点for循环sum处理,for (; right < len; right++){
			//要更新sum值
			return max(sum, right-left+1); //+1的原因是right--,
			//此时right不是同类树的下一个下标,而是同类树的最后一个下标,所以要+1
			
			return sum;
		

	
	}
};

在这里插入图片描述

OVER! 感谢阅读。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章