Skip to content

Commit 80947bb

Browse files
committed
feat: add solutions to lc problem: No.0904
No.0904.Fruit Into Baskets
1 parent 937eb8d commit 80947bb

File tree

6 files changed

+385
-73
lines changed

6 files changed

+385
-73
lines changed

solution/0900-0999/0904.Fruit Into Baskets/README.md

Lines changed: 182 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,39 @@
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70-
“计数器 + 滑动窗口”实现。
70+
**方法一:哈希表 + 滑动窗口**
71+
72+
我们用哈希表 $cnt$ 维护当前窗口内的水果种类以及对应的数量,用双指针 $j$ 和 $i$ 维护窗口的左右边界。
73+
74+
遍历数组 `fruits`,将当前水果 $x$ 加入窗口,即 $cnt[x]++$,然后判断当前窗口内的水果种类是否超过了 $2$ 种,如果超过了 $2$ 种,就需要将窗口的左边界 $j$ 右移,直到窗口内的水果种类不超过 $2$ 种为止。然后更新答案,即 $ans = \max(ans, i - j + 1)$。
75+
76+
遍历结束后,即可得到最终的答案。
77+
78+
```
79+
1 2 3 2 2 1 4
80+
^ ^
81+
j i
82+
83+
84+
1 2 3 2 2 1 4
85+
^ ^
86+
j i
87+
88+
89+
1 2 3 2 2 1 4
90+
^ ^
91+
j i
92+
```
93+
94+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `fruits` 的长度。
95+
96+
**方法二:滑动窗口优化**
97+
98+
在方法一中,我们发现,窗口大小会时而变大,时而变小,这就需要我们每一次更新答案。
99+
100+
但本题实际上求的是水果的最大数目,也就是“最大”的窗口,我们没有必要缩小窗口,只需要让窗口单调增大。于是代码就少了每次更新答案的操作,只需要在遍历结束后将此时的窗口大小作为答案返回即可。
101+
102+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `fruits` 的长度。
71103

72104
<!-- tabs:start -->
73105

@@ -77,18 +109,35 @@
77109

78110
```python
79111
class Solution:
80-
def totalFruit(self, tree: List[int]) -> int:
81-
counter = Counter()
82-
i = res = 0
83-
for j, type in enumerate(tree):
84-
counter[type] += 1
85-
while len(counter) > 2:
86-
counter[tree[i]] -= 1
87-
if counter[tree[i]] == 0:
88-
counter.pop(tree[i])
89-
i += 1
90-
res = max(res, j - i + 1)
91-
return res
112+
def totalFruit(self, fruits: List[int]) -> int:
113+
cnt = Counter()
114+
ans = j = 0
115+
for i, x in enumerate(fruits):
116+
cnt[x] += 1
117+
while len(cnt) > 2:
118+
y = fruits[j]
119+
cnt[y] -= 1
120+
if cnt[y] == 0:
121+
cnt.pop(y)
122+
j += 1
123+
ans = max(ans, i - j + 1)
124+
return ans
125+
```
126+
127+
```python
128+
class Solution:
129+
def totalFruit(self, fruits: List[int]) -> int:
130+
cnt = Counter()
131+
j = 0
132+
for x in fruits:
133+
cnt[x] += 1
134+
if len(cnt) > 2:
135+
y = fruits[j]
136+
cnt[y] -= 1
137+
if cnt[y] == 0:
138+
cnt.pop(y)
139+
j += 1
140+
return len(fruits) - j
92141
```
93142

94143
### **Java**
@@ -97,25 +146,133 @@ class Solution:
97146

98147
```java
99148
class Solution {
100-
public int totalFruit(int[] tree) {
101-
Map<Integer, Integer> counter = new HashMap<>();
102-
int i = 0, res = 0;
103-
for (int j = 0; j < tree.length; ++j) {
104-
counter.put(tree[j], counter.getOrDefault(tree[j], 0) + 1);
105-
while (counter.size() > 2) {
106-
counter.put(tree[i], counter.get(tree[i]) - 1);
107-
if (counter.get(tree[i]) == 0) {
108-
counter.remove(tree[i]);
149+
public int totalFruit(int[] fruits) {
150+
Map<Integer, Integer> cnt = new HashMap<>();
151+
int ans = 0;
152+
for (int i = 0, j = 0; i < fruits.length; ++i) {
153+
int x = fruits[i];
154+
cnt.put(x, cnt.getOrDefault(x, 0) + 1);
155+
while (cnt.size() > 2) {
156+
int y = fruits[j++];
157+
cnt.put(y, cnt.get(y) - 1);
158+
if (cnt.get(y) == 0) {
159+
cnt.remove(y);
109160
}
110-
++i;
111161
}
112-
res = Math.max(res, j - i + 1);
162+
ans = Math.max(ans, i - j + 1);
113163
}
114-
return res;
164+
return ans;
115165
}
116166
}
117167
```
118168

169+
```java
170+
class Solution {
171+
public int totalFruit(int[] fruits) {
172+
Map<Integer, Integer> cnt = new HashMap<>();
173+
int j = 0, n = fruits.length;
174+
for (int x : fruits) {
175+
cnt.put(x, cnt.getOrDefault(x, 0) + 1);
176+
if (cnt.size() > 2) {
177+
int y = fruits[j++];
178+
cnt.put(y, cnt.get(y) - 1);
179+
if (cnt.get(y) == 0) {
180+
cnt.remove(y);
181+
}
182+
}
183+
}
184+
return n - j;
185+
}
186+
}
187+
```
188+
189+
### **C++**
190+
191+
```cpp
192+
class Solution {
193+
public:
194+
int totalFruit(vector<int>& fruits) {
195+
unordered_map<int, int> cnt;
196+
int ans = 0;
197+
for (int i = 0, j = 0; i < fruits.size(); ++i) {
198+
int x = fruits[i];
199+
++cnt[x];
200+
while (cnt.size() > 2) {
201+
int y = fruits[j++];
202+
if (--cnt[y] == 0) cnt.erase(y);
203+
}
204+
ans = max(ans, i - j + 1);
205+
}
206+
return ans;
207+
}
208+
};
209+
```
210+
211+
```cpp
212+
class Solution {
213+
public:
214+
int totalFruit(vector<int>& fruits) {
215+
unordered_map<int, int> cnt;
216+
int j = 0, n = fruits.size();
217+
for (int& x : fruits) {
218+
++cnt[x];
219+
if (cnt.size() > 2) {
220+
int y = fruits[j++];
221+
if (--cnt[y] == 0) cnt.erase(y);
222+
}
223+
}
224+
return n - j;
225+
}
226+
};
227+
```
228+
229+
### **Go**
230+
231+
```go
232+
func totalFruit(fruits []int) int {
233+
cnt := map[int]int{}
234+
ans, j := 0, 0
235+
for i, x := range fruits {
236+
cnt[x]++
237+
for ; len(cnt) > 2; j++ {
238+
y := fruits[j]
239+
cnt[y]--
240+
if cnt[y] == 0 {
241+
delete(cnt, y)
242+
}
243+
}
244+
ans = max(ans, i-j+1)
245+
}
246+
return ans
247+
}
248+
249+
func max(a, b int) int {
250+
if a > b {
251+
return a
252+
}
253+
return b
254+
}
255+
```
256+
257+
```go
258+
func totalFruit(fruits []int) int {
259+
cnt := map[int]int{}
260+
j := 0
261+
for _, x := range fruits {
262+
cnt[x]++
263+
if len(cnt) > 2 {
264+
y := fruits[j]
265+
cnt[y]--
266+
if cnt[y] == 0 {
267+
delete(cnt, y)
268+
}
269+
j++
270+
}
271+
}
272+
return len(fruits) - j
273+
}
274+
```
275+
119276
### **...**
120277

121278
```

0 commit comments

Comments
 (0)