Medium
题目描述
你想要在花园中给 n 棵植物浇水,你有一个浇水壶。植物排成一行,标记为从 0 到 n - 1,从左到右第 i 棵植物位于 x = i 位置。在 x = -1 处有一条河,你可以在那里重新装满浇水壶。
每棵植物需要特定数量的水。你将按以下方式给植物浇水:
- 按从左到右的顺序给植物浇水。
- 给当前植物浇水后,如果你没有足够的水来完全浇灌下一棵植物,则返回河边重新装满浇水壶。
- 你不能提前重新装满浇水壶。
你最初在河边(即 x = -1)。在 x 轴上移动一个单位需要一步。
给定一个长度为 n 的 0 索引整数数组 plants,其中 plants[i] 是第 i 棵植物需要的水量,以及一个整数 capacity 表示浇水壶的容量,返回给所有植物浇水所需的步数。
示例 1:
输入:plants = [2,2,3,3], capacity = 5
输出:14
解释:从河边开始,浇水壶装满:
- 走到植物 0(1 步)并浇水。浇水壶有 3 单位水。
- 走到植物 1(1 步)并浇水。浇水壶有 1 单位水。
- 由于不能完全浇灌植物 2,走回河边重新装满(2 步)。
- 走到植物 2(3 步)并浇水。浇水壶有 2 单位水。
- 由于不能完全浇灌植物 3,走回河边重新装满(3 步)。
- 走到植物 3(4 步)并浇水。
所需步数 = 1 + 1 + 2 + 3 + 3 + 4 = 14。
示例 2:
输入:plants = [1,1,1,4,2,3], capacity = 4
输出:30
示例 3:
输入:plants = [7,7,7,7,7,7,7], capacity = 8
输出:49
约束条件:
- n == plants.length
- 1 <= n <= 1000
- 1 <= plants[i] <= 10^6
- max(plants[i]) <= capacity <= 10^9
解题思路
解题思路
这是一个模拟题,我们需要按照题目描述的规则来模拟整个浇水过程。
基本思路
- 初始状态:我们从河边(位置 -1)开始,浇水壶已装满(容量为 capacity)
- 移动规则:每次移动一个位置需要 1 步
- 浇水规则:
- 按从左到右的顺序浇水
- 给当前植物浇水后,检查剩余水量是否足够浇下一棵植物
- 如果不够,必须回到河边重新装满
算法步骤
- 初始化当前水量为满容量,当前位置为 -1,总步数为 0
- 遍历每棵植物:
- 计算从当前位置走到植物 i 的步数
- 给植物 i 浇水,更新剩余水量
- 如果这不是最后一棵植物,检查剩余水量是否足够浇下一棵植物
- 如果不够,计算回到河边的步数,重新装满水壶
- 返回总步数
这种方法的时间复杂度是 O(n),空间复杂度是 O(1),是最优解法。
代码实现
class Solution {
public:
int wateringPlants(vector<int>& plants, int capacity) {
int steps = 0;
int currentWater = capacity;
int currentPos = -1;
for (int i = 0; i < plants.size(); i++) {
// 走到当前植物的步数
steps += i - currentPos;
currentPos = i;
// 给当前植物浇水
currentWater -= plants[i];
// 如果不是最后一棵植物,检查是否需要回河边装水
if (i < plants.size() - 1 && currentWater < plants[i + 1]) {
// 回到河边的步数
steps += i + 1;
currentPos = -1;
currentWater = capacity;
}
}
return steps;
}
};
class Solution:
def wateringPlants(self, plants: List[int], capacity: int) -> int:
steps = 0
current_water = capacity
current_pos = -1
for i in range(len(plants)):
# 走到当前植物的步数
steps += i - current_pos
current_pos = i
# 给当前植物浇水
current_water -= plants[i]
# 如果不是最后一棵植物,检查是否需要回河边装水
if i < len(plants) - 1 and current_water < plants[i + 1]:
# 回到河边的步数
steps += i + 1
current_pos = -1
current_water = capacity
return steps
public class Solution {
public int WateringPlants(int[] plants, int capacity) {
int steps = 0;
int currentWater = capacity;
int currentPos = -1;
for (int i = 0; i < plants.Length; i++) {
// 走到当前植物的步数
steps += i - currentPos;
currentPos = i;
// 给当前植物浇水
currentWater -= plants[i];
// 如果不是最后一棵植物,检查是否需要回河边装水
if (i < plants.Length - 1 && currentWater < plants[i + 1]) {
// 回到河边的步数
steps += i + 1;
currentPos = -1;
currentWater = capacity;
}
}
return steps;
}
}
var wateringPlants = function(plants, capacity) {
let steps = 0;
let currentWater = capacity;
let currentPos = -1;
for (let i = 0; i < plants.length; i++) {
// 走到当前植物的步数
steps += i - currentPos;
currentPos = i;
// 给当前植物浇水
currentWater -= plants[i];
// 如果不是最后一棵植物,检查是否需要回河边装水
if (i < plants.length - 1 && currentWater < plants[i + 1]) {
// 回到河边的步数
steps += i + 1;
currentPos = -1;
currentWater = capacity;
}
}
return steps;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 需要遍历所有植物一次,每个植物的处理时间为常数 |
| 空间复杂度 | O(1) | 只使用了常数个额外变量来记录状态 |
相关题目
- . Watering Plants II (Medium)