《代码随想录》学习笔记,原链接:长度最小的子数组相关题目推荐
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
if len(fruits) <= 2: # 特殊处理,当果树个数不超过两棵时,直接返回
return len(fruits)
slow, type_num, result = 0, 1, 0 # 构建双指针,当前装入篮子的水果种类,统计最大水果
fruit_1, fruit_2 = fruits[0], float("inf") # 记录当前篮子里的水果种类(设置这两个变量的目的只是为了防止超时)
for fast in range(1, len(fruits)): # 遍历fruits数组
if fruits[fast] not in [fruit_1, fruit_2]: # 当前遍历的水果在之前没有出现
type_num += 1 # 种类加一
if type_num > 2: # 原本两个篮子已装满
result = max(result, fast - slow) # 记录当前可以收获的最大水果数量
for i in range(fast - 1, slow - 1, -1):
if fruits[i] != fruits[fast - 1]:
slow = i + 1
break # 找到fast前面的种类的水果的起始位置后,跳出for循环
fruit_1, fruit_2 = fruits[slow], fruits[fast] # 记录此时两种水果种类
type_num = 2 # 更新篮子里水果种类
else: # 原本两个篮子没装满
fruit_2 = fruits[fast] # 记录第二种水果
result = max(result, fast + 1 - slow) # 再次更新,处理整个数组的最后一段只有两种水果的情况
return result
【注】
- 对于果树个数不超过两棵的情况要进行特殊处理
- 为了避免判断当前fast遍历的果树种类之前是否出现过,需要设置[fruit_1, fruit_2]来记录篮子里的水果种类,防止直接查询原fruits数组时出现超时
- 经过演算,当fast访问到第三种水果时,fast - slow的值就是前两种水果的数量
- 更新slow时,是要把slow指向fast访问的前一种水果的开头位置,在找到开头位置后,及时break跳出循环
- 当开始访问第三种水果时,要对于[fruit_1, fruit_2]进行更新
- 最后需要再次对result进行更新,避免fruits数组结尾位置的水果在[fruit_1, fruit_2]范围内,而未触发更新result的情况