0. 題幹
leetcode 904:
在一排樹中,第 i 棵樹產生 tree[i] 型的水果。
你可以從你選擇的任何樹開始,然後重複執行以下步驟:
- 把這棵樹上的水果放進你的籃子裏。如果你做不到,就停下來。
- 移動到當前樹右側的下一棵樹。如果右邊沒有樹,就停下來。
請注意,在選擇一顆樹後,你沒有任何選擇:你必須執行步驟 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! 感謝閱讀。