LeetCode:904. Fruit Into Baskets - Python

问题描述:

904. 水果成篮

在一排树中,第i棵树产生tree[i]型的水果。
你可以从你选择的任何树开始,然后重复执行以下步骤:

  1. 把这棵树上的水果放进你的篮子里。如果你做不到,就停下来。
  2. 移动到当前树右侧的下一棵树。如果右边没有树,就停下来。

请注意,在选择一颗树后,你没有任何选择:你必须执行步骤 1,然后执行步骤 2,然后返回步骤 1,然后执行步骤 2,依此类推,直至停止。

你有两个篮子,每个篮子可以携带任何数量的水果,但你希望每个篮子只携带一种类型的水果。
用这个程序你能收集的水果总量是多少?

示例 1:

输入:[1,2,1]
输出:3
解释:我们可以收集 [1,2,1]。

示例 2:

输入:[0,1,2,2]
输出:3
解释:我们可以收集 [1,2,2].如果我们从第一棵树开始,我们将只能收集到 [0, 1]。

提示:

  • 1 <= tree.length <= 40000
  • 0 <= tree[i] < tree.length

问题分析:

先看看题目,要注意的几点,第一,tree[i] 表示水果的类型,不是水果的个数哦。第二,两个篮子,只能获取两种水果,第三,求收集水果的总量,感觉可以简单理解为采摘树的棵树。现在就可以理解为,就是,获取 tree[] 其中的一个最长子序列,而且这个子序列,只有两种水果。
解题思路:
(1)使用双指针法或者是滑动窗口法,遍历整个 tree[] ,找到一个小区间内只有两个水果,而且,这个区间的长度是所有子区间最长的,即可。
(2)可以使用 cnt = {} 来保存一个区间的元素统计数,用i表示这个滑动窗口的左端,j表示换的窗口的右端,j随着遍历tree[] 一直向右端走。
(3)每次遍历一个元素,就要更新 cnt = {} 并判断长度是否超过了2,如果超过了,此时就开始处理左端点ii开始向右移动,同时更新 cnt = {} ,直到 cnt = {} 的长度小于等于2,并更新保留一次最优的结果。依次类推,直到结束。

Python3实现:

class Solution:
    def totalFruit(self, tree):
        cnt = {}
        i = res = 0
        for j, v in enumerate(tree):
            cnt[v] = cnt.get(v, 0) + 1  # cnt.get(v, 0) 从字典里获取一个数,如果不存在就默认为 0
            while len(cnt) > 2:  # 如果字典中的元素大于 2
                cnt[tree[i]] -= 1
                if cnt[tree[i]] == 0:
                    del cnt[tree[i]]
                i += 1
            res = max(res, j - i + 1)  # 结束一个区间,更新一次最优结果
        return res


if __name__ == '__main__':
    solu = Solution()
    tree = [3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4]
    print(solu.totalFruit(tree))

声明: 总结学习,有问题可以批评指正,大神可以略过哦

题目链接:leetcode-cn.com/problems/fruit-into-baskets/description/
参考链接:leetcode.com/problems/fruit-into-baskets/discuss/170740/C%2B%2BPython-Sliding-Window

猜你喜欢

转载自blog.csdn.net/XX_123_1_RJ/article/details/82828570
今日推荐