返回

Java&C++题解与拓展——leetcode904.水果成篮【么的新知识】

后端

Java&C++题解与拓展——leetcode904.水果成篮【么的新知识】
大家好,我是编程爱好者,也是LeetCode的忠实粉丝,今天我要与大家分享我解题leetcode904.水果成篮时的收获与心得。

题目

leetcode904.水果成篮是一个经典的滑动窗口问题,如下:

在一个水果篮子中,摆放着两种不同种类的水果。每种水果可以用一个字母表示,比如'A'和'B'。现在,你需要从这个篮子中取出最多数量的水果,并且确保篮子中同时含有两种不同的水果。

解题思路

为了解决这个问题,我们可以使用两种方法:两指针法和滑动窗口法。

两指针法

两指针法是一种常用的滑动窗口算法,它的核心思想是使用两个指针来维护一个窗口,窗口的大小由两个指针的距离决定。在这个问题中,我们可以使用两个指针left和right分别指向窗口的左边界和右边界。

public int totalFruit(int[] fruits) {
    int left = 0, right = 0;
    int maxLen = 0;
    Map<Integer, Integer> fruitCount = new HashMap<>();

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

    return maxLen;
}
int totalFruit(vector<int>& fruits) {
    int left = 0, right = 0;
    int maxLen = 0;
    unordered_map<int, int> fruitCount;

    while (right < fruits.size()) {
        fruitCount[fruits[right]]++;
        while (fruitCount.size() > 2) {
            fruitCount[fruits[left]]--;
            if (fruitCount[fruits[left]] == 0) {
                fruitCount.erase(fruits[left]);
            }
            left++;
        }
        maxLen = max(maxLen, right - left + 1);
        right++;
    }

    return maxLen;
}

滑动窗口法

滑动窗口法也是一种常用的滑动窗口算法,它的核心思想是使用一个固定大小的窗口来遍历数组。在这个问题中,我们可以使用一个大小为2的窗口来遍历fruits数组。

public int totalFruit(int[] fruits) {
    int left = 0, right = 0;
    int maxLen = 0;
    Set<Integer> fruitSet = new HashSet<>();

    while (right < fruits.length) {
        if (fruitSet.size() < 2) {
            fruitSet.add(fruits[right]);
            maxLen = Math.max(maxLen, right - left + 1);
            right++;
        } else {
            fruitSet.remove(fruits[left]);
            left++;
        }
    }

    return maxLen;
}
int totalFruit(vector<int>& fruits) {
    int left = 0, right = 0;
    int maxLen = 0;
    set<int> fruitSet;

    while (right < fruits.size()) {
        if (fruitSet.size() < 2) {
            fruitSet.insert(fruits[right]);
            maxLen = max(maxLen, right - left + 1);
            right++;
        } else {
            fruitSet.erase(fruits[left]);
            left++;
        }
    }

    return maxLen;
}

贪心算法

贪心算法是一种常见的算法策略,它的核心思想是每次都做出最优的选择。在这个问题中,我们可以使用贪心算法来选择下一个要取出的水果。

public int totalFruit(int[] fruits) {
    int maxLen = 0;
    int left = 0, right = 0;
    Map<Integer, Integer> fruitCount = new HashMap<>();

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

    return maxLen;
}
int totalFruit(vector<int>& fruits) {
    int maxLen = 0;
    int left = 0, right = 0;
    unordered_map<int, int> fruitCount;

    while (right < fruits.size()) {
        fruitCount[fruits[right]]++;
        while (fruitCount.size() > 2) {
            fruitCount[fruits[left]]--;
            if (fruitCount[fruits[left]] == 0) {
                fruitCount.erase(fruits[left]);
            }
            left++;
        }
        maxLen = max(maxLen, right - left + 1);
        right++;
    }

    return maxLen;
}

学习记录

通过解决leetcode904.水果成篮这一问题,我学习到了以下几点:

  • 两指针法、滑动窗口法和贪心算法都是解决滑动窗口问题的有效方法。
  • HashMap和HashSet是Java中常用的数据结构,可以用来存储和管理数据。
  • Map.getOrDefault()方法可以获取Map中的值,如果该值不存在,则返回默认值。
  • Map.remove()方法可以从Map中删除一个键值对。

我希望这次分享对大家有所帮助。如果您有任何问题,请随时留言。