核心求解思路为滑动窗口:使用 j 和 i 分别代表滑动窗口的两端,窗口种类不超过 $2$ 种为合法。
Java 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { publicinttotalFruit(int[] fruits) { intn= fruits.length, ans = 0; int[] cnts = newint[n + 10]; for (inti=0, j = 0, tot = 0; i < n; i++) { if (++cnts[fruits[i]] == 1) tot++; while (tot > 2) { if (--cnts[fruits[j++]] == 0) tot--; } ans = Math.max(ans, i - j + 1); } return ans; } }
C++ 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { public: inttotalFruit(vector<int>& fruits){ int n = fruits.size(), ans = 0; unordered_map<int, int> cnts; for (int i = 0, j = 0, tot = 0; i < n; i++) { if (++cnts[fruits[i]] == 1) tot++; while (tot > 2) { if (--cnts[fruits[j++]] == 0) tot--; } ans = max(ans, i - j + 1); } return ans; } };
Python 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution: deftotalFruit(self, fruits: List[int]) -> int: n, ans = len(fruits), 0 j, tot = 0, 0 cnts = defaultdict(int) for i inrange(n): cnts[fruits[i]] += 1 if cnts[fruits[i]] == 1: tot += 1 while tot > 2: cnts[fruits[j]] -= 1 if cnts[fruits[j]] == 0: tot -= 1 j += 1 ans = max(ans, i - j + 1) return ans
TypeScript 代码:
1 2 3 4 5 6 7 8 9 10 11 12
functiontotalFruit(fruits: number[]): number { let n = fruits.length, ans = 0 const cnts = newArray<number>(n + 10).fill(0) for (let i = 0, j = 0, tot = 0; i < n; i++) { if (++cnts[fruits[i]] == 1) tot++ while (tot > 2) { if (--cnts[fruits[j++]] == 0) tot-- } ans = Math.max(ans, i - j + 1) } return ans }