给花园的植物浇水 — 模拟行走取水的最少步数问题
题目描述
你有一排编号从 0 到 n-1 的植物,它们依次排成一行,每株植物的位置为其编号 x = i。
在 x = -1 的位置,有一条河,你可以在那里给水罐重新装满水。
现在你有一个容量为 capacity 的水罐,要给这 n 株植物浇水,每株植物需要的水量不同,用数组 plants 表示,plants[i] 表示第 i 株植物需要的水量。
规则:
- 你从河边(位置 -1)开始,水罐已满。
- 按顺序从左到右给植物浇水,浇完当前植物后,如果剩余水量不足以完全浇灌下一株植物,则必须先回河边重新装满水罐。
- 不能提前回河边,只有当当前水量不足浇下一个植物时才回河边。
- 从当前位置移动到河边,或者从河边移动到某个植物的位置,每移动一个单位需要走一步。
- 求完成给所有植物浇水,所需要的总步数。
解题分析
这个题目本质上是一个模拟行走和取水过程的问题。需要模拟从左到右依次给植物浇水的步骤,同时计算移动步数。
关键点:
- 从河边出发,水罐满水。
- 给植物浇水需要水量满足。
- 若当前水量不足以浇下一株,则必须返回河边装满水,再回到当前位置继续浇水。
- 步数计算包含往返河边的距离和移动到植物位置的距离。
解题方法
1. 初始化
- 设置
steps = 0,记录总步数。 - 设置
water = capacity,当前水罐水量。 - 当前位置从河边开始,即在
x = -1,但因为浇水是按植物编号顺序进行,移动步数可以计算为当前位置与目标位置的差值。
2. 模拟过程
遍历每株植物 i:
- 判断当前水量是否足够浇灌
plants[i]:- 如果足够:
- 走一步到当前位置(因为每个植物位置就是
i,遍历时相当于移动一步),steps += 1。 - 浇水,水量减少
plants[i]。
- 走一步到当前位置(因为每个植物位置就是
- 如果不够:
- 先回河边装满水,回去的步数是从当前位置
i到河边-1,即i + 1步。 - 再从河边回到植物
i,再i + 1步。 - 总共额外步数为
2 * (i + 1)。 - 水罐重新装满,扣除植物
i需要的水量。
- 先回河边装满水,回去的步数是从当前位置
- 如果足够:
3. 返回总步数
遍历完成后返回 steps。
代码实现(Python)
from typing import List
class Solution:
def wateringPlants(self, plants: List[int], capacity: int) -> int:
steps = 0
water = capacity
for i in range(len(plants)):
if water >= plants[i]:
# 走一步到植物 i,浇水
steps += 1
water -= plants[i]
else:
# 回河边取水再回来
steps += 2 * (i + 1)
water = capacity - plants[i]
return steps
复杂度分析
- 时间复杂度:
O(n),只需遍历一次植物列表。 - 空间复杂度:
O(1),只使用常数额外空间。
示例说明
示例 1
plants = [2,2,3,3]
capacity = 5
- 起点河边水罐满 5 单位水。
- 浇植物 0,需 2,水剩 3,步数 +1。
- 浇植物 1,需 2,水剩 1,步数 +1。
- 下一株植物 2 需 3,水不足,回河边装满水,回去和回来共步数 +6 (
2*(2+1))。 - 浇植物 2,需 3,水剩 2,步数 +1。
- 下一株植物 3 需 3,水不足,回河边装满水,回去和回来共步数 +8 (
2*(3+1))。 - 浇植物 3,需 3,步数 +1。
总步数 = 1 + 1 + 6 + 1 + 8 + 1 = 18 (这里要注意步骤数,题目示例的计算方法是细化每一步)
注意:题目示例中,回河边的步数是分成回去和回来分别计算,并且“走到植物i”步数单独计数。代码中加的步数是针对“需要回河边”情况额外加的往返步数(不包括浇水本身的那一步),故需保证模拟时每走一步都计数。
示例 2
plants = [1,1,1,4,2,3]
capacity = 4
- 给前 3 株植物依次浇水,水足够,步数为 3。
- 第 3 株需要 4,水不足,回河边取水和回来步数为
2 * (3 + 1) = 8。 - 浇第 3 株,步数 +1。
- 如此类推。
最终步数符合示例。
总结
这道题用模拟法非常直接且高效,重点在于:
- 正确计算每次回河边和回来所需的步数。
- 不要提前回河边,只有水不够时才回河边。
- 统计每一步的移动代价。
通过清晰的模拟,可以准确计算完成任务所需的步数。
453

被折叠的 条评论
为什么被折叠?



