农场采摘水果问题| 豆包MarsCode AI刷题

158 阅读3分钟

问题描述

小U正在探访一座农场,农场的果树排成一列,用整数数组 fruits 表示,每个元素 fruits[i] 是第 i 棵树上的水果种类。小U有两个篮子,每个篮子只能装一种类型的水果,而且每个篮子可以装无限量的水果。小U从任意一棵树开始,必须从每棵树上恰好采摘一个水果,并且只能装入符合篮子中水果类型的果实。如果某棵树上的水果类型不符合篮子中的水果类型,则必须停止采摘。请你帮助小U计算他最多可以采摘多少个水果。例如:当 fruits = [1,2,3,2,2] 时,小U最多可以采摘的树是从第2棵开始,采摘到最后的 4 棵树,结果为 [2,3,2,2]。

代码原理

代码使用了滑动窗口算法来解决这个问题。滑动窗口算法是一种常用的双指针技术,用于解决数组和字符串相关的问题。

滑动窗口算法的工作原理

  1. 扩展窗口

    • 通过移动 end 指针,将新的水果加入窗口,并更新 fruit_count
    • 如果窗口中水果类型不超过两种,继续扩展窗口。
  2. 收缩窗口

    • 如果窗口中水果类型超过两种,移动 start 指针,收缩窗口,直到窗口中只包含两种水果类型。
    • 在收缩窗口的过程中,更新 fruit_count,减少或移除不再在窗口中的水果。
  3. 更新最大值

    • 在每次扩展或收缩窗口后,计算当前窗口的长度(end - start + 1),并更新 max_fruits

代码思路

  1. 初始化变量

    • max_fruits:用于记录最大采摘数量,初始值为0。
    • start:窗口的起始位置,初始值为0。
    • fruit_count:一个字典,用于记录当前窗口中每种水果的数量。
  2. 遍历数组

    • for end in range(len(fruits)):遍历数组,end 表示窗口的结束位置。
    • fruit = fruits[end]:获取当前水果。
    • if fruit in fruit_count:如果当前水果已经在字典中,增加其数量。
    • else:如果当前水果不在字典中,将其添加到字典并设置数量为1。
  3. 收缩窗口

    • while len(fruit_count) > 2:如果窗口中水果类型超过两种,收缩窗口。
    • start_fruit = fruits[start]:获取窗口起始位置的水果。
    • fruit_count[start_fruit] -= 1:减少该水果的数量。
    • if fruit_count[start_fruit] == 0:如果该水果数量为0,从字典中移除。
    • start += 1:移动窗口的起始位置。
  4. 更新最大采摘数量

    • max_fruits = max(max_fruits, end - start + 1):更新最大采摘数量,当前窗口的长度为 end - start + 1
  5. 返回最大采摘数量

    • return max_fruits:返回最大采摘数量。

代码

def solution(fruits: list) -> int:

max_fruits = 0
start = 0
fruit_count = {}
for end in range(len(fruits)):
    fruit = fruits[end]
    if fruit in fruit_count:
        fruit_count[fruit] += 1
    else:
        fruit_count[fruit] = 1
        
    while len(fruit_count) > 2:
        start_fruit = fruits[start]
        fruit_count[start_fruit] -= 1
        if fruit_count[start_fruit] == 0:
            del fruit_count[start_fruit]
        start += 1
    max_fruits = max(max_fruits, end - start + 1)
return max_fruits`

`