[LeetCode]Fruit Into Baskets
原題
In a row of trees, thei
-th tree produces fruit with type tree[i]
.
Youstart at any tree of your choice , then repeatedly perform the following steps:
- Add one piece of fruit from this tree to your baskets. If you cannot, stop.
- Move to the next tree to the right of the current tree. If there is no tree to the right, stop.
Note that you do not have any choice after the initial choice of starting tree: you must perform step 1, then step 2, then back to step 1, then step 2, and so on until you stop.
You have two baskets, and each basket can carry any quantity of fruit, but you want each basket to only carry one type of fruit each.
What is the total amount of fruit you can collect with this procedure?
Example 1:
Input: [1,2,1] Output: 3 Explanation: We can collect [1,2,1].
Example 2:
Input: [0,1,2,2] Output: 3 Explanation: We can collect [1,2,2]. If we started at the first tree, we would only collect [0, 1].
Example 3:
Input: [1,2,3,2,2] Output: 4 Explanation: We can collect [2,3,2,2]. If we started at the first tree, we would only collect [1, 2].
Example 4:
Input: [3,3,3,1,2,1,1,2,3,3,4] Output: 5 Explanation: We can collect [1,2,1,1,2]. If we started at the first tree or the eighth tree, we would only collect 4 fruits.
Note:
1 <= tree.length <= 40000 0 <= tree[i] < tree.length
題解
該題屬於雙指標(Two Pointers)範疇,主要的思路是利用兩個指標來構造一個滑動視窗,且要求視窗中的元素型別不得超過2種。所以,經過一遍for迴圈,即可拿到所有不超過兩個型別元素的視窗長度,即拿到其中最大的長度。
所以,難度在於怎麼來構造這個視窗。這裡,我們可以巧妙的利用對映(Map)這種資料結構,用對映來維護for迴圈過程中,經過的資料型別總數,以及每種型別的個數。
以原題中第一個案例為例,在第一次for迴圈中,我們將第一個元素加入到map中,如下:
map m; m.insert(make_pair(1, 1)); // 第一個元素代表型別為1,第二個元素代表型別為1的出現的個數
同時,可以很容易的拿到某時刻的狀態資訊:
m.size(); // 當前不同型別的總數 m.find(1)->second; // 型別為1的出現的次數
程式碼
class Solution { public: int totalFruit(vector<int>& tree) { map<int, int> m; map<int, int>::iterator it; int l = 0, r = 0, len = tree.size(), a = 0; while (r < len) { if (m.size() <= 2) { it = m.find(tree[r]); if (it != m.end()) { it->second++; m.insert(make_pair(tree[r], it->second + 1)); } else { m.insert(make_pair(tree[r], 1)); } r++; if (a < r - l) a = r - l; } else { it = m.find(tree[l]); m.erase(tree[l]); if (it->second != 1) { m.erase(tree[l]); m.insert(make_pair(tree[l], it->second - 1)); it = m.find(tree[l]); } l++; } } return a; } };
原題:ofollow,noindex">https://leetcode.com/problems/fruit-into-baskets/description/
Github 原始碼:https://github.com/GenialX/leetcode-cpp/blob/master/2018/09/fruit-into-baskets.cpp