返回

破解 leetcode 904:装水果的篮子 - 巧用滑动窗口法,篮满为盈

见解分享

如何破解 LeetCode 904:装水果的篮子

破解 LeetCode 904

作为算法竞赛爱好者,我们经常面对各种难题,其中 LeetCode 904「装水果的篮子」就是一道令人头疼的题目。它要求我们找到最多不同种类的水果,同时满足特定限制条件。破解这道题的关键在于掌握强大的算法策略——滑动窗口法。

滑动窗口法

滑动窗口法是一种动态规划技术,用于解决寻找特定子数组的问题。它的本质是使用一个窗口在数组中移动,并在移动过程中不断更新窗口内的信息。通过这种方式,我们可以高效地找到满足特定条件的子数组。

破解步骤

解决 LeetCode 904 的具体步骤如下:

  1. 初始化窗口: 以窗口大小为 2,遍历数组,记录窗口内的不同水果种类数。
  2. 滑动窗口: 移动窗口,每移动一步,更新窗口内的信息:
    • 如果窗口内水果种类数少于 2,则扩大窗口。
    • 如果窗口内水果种类数达到 2,则缩小窗口,直到窗口内水果种类数减少为 1。
  3. 记录最大种类数: 在窗口移动过程中,记录窗口内不同水果种类数的最大值。

代码示例

为了加深理解,我们提供一个用 Java 编写的代码示例:

import java.util.HashMap;
import java.util.Map;

public class Solution {
    public int totalFruit(int[] fruits) {
        if (fruits == null || fruits.length == 0) {
            return 0;
        }

        int left = 0, right = 0, maxFruit = 0, count = 0;
        Map<Integer, Integer> fruitCount = new HashMap<>();

        while (right < fruits.length) {
            if (fruitCount.size() <= 2) {
                fruitCount.put(fruits[right], fruitCount.getOrDefault(fruits[right], 0) + 1);
                maxFruit = Math.max(maxFruit, ++count);
                right++;
            } else {
                while (fruitCount.size() > 2) {
                    int leftFruit = fruits[left];
                    fruitCount.put(leftFruit, fruitCount.get(leftFruit) - 1);
                    if (fruitCount.get(leftFruit) == 0) {
                        fruitCount.remove(leftFruit);
                    }
                    left++;
                    count--;
                }
            }
        }

        return maxFruit;
    }
}

实例分析

考虑数组 [1, 2, 1],使用滑动窗口法:

  • 窗口初始大小为 2,窗口为 [1, 2]
  • 移动窗口,窗口变为 [2, 1]
  • 窗口内水果种类数为 1,扩大窗口,窗口变为 [2, 1, 2]
  • 移动窗口,窗口变为 [1, 2, 2]
  • 窗口内水果种类数为 2,缩小窗口,窗口变为 [1, 2]
  • 窗口内水果种类数为 2,再次缩小窗口,窗口变为 [1]
  • 窗口内水果种类数为 1,记录最大种类数为 2。

常见问题解答

  1. 为什么滑动窗口法适用于这个问题?

答:滑动窗口法适用于这个问题,因为它允许我们以高效的方式维护窗口内的水果种类数,并动态地调整窗口的大小以满足特定条件。

  1. 窗口大小是否可以任意设置?

答:窗口大小可以根据问题要求进行调整。对于 LeetCode 904,窗口大小设置为 2,因为题目限制我们最多携带两种不同的水果。

  1. 缩小窗口时如何决定删除哪个水果?

答:在缩小窗口时,我们通常删除窗口左端的最左边的水果。这样可以确保窗口内保持两种不同的水果,并防止窗口内水果种类数超过限制。

  1. 如何优化代码?

答:优化代码的一个方法是使用双指针(left 和 right)来维护窗口,而不是使用额外的哈希表来存储水果计数。这可以减少空间复杂度并提高运行时效率。

  1. LeetCode 904 还有哪些其他解法?

答:除了滑动窗口法之外,解决 LeetCode 904 还有其他解法,例如哈希表法和前缀和法。然而,滑动窗口法通常是解决这类问题的最有效方法。

结论

掌握滑动窗口法是破解 LeetCode 904 的关键。通过理解其工作原理和应用,我们可以轻松解决这类「寻找子数组」问题,并进一步提高我们的算法竞赛技能。