倒水
难度:
标签:
题目描述
代码结果
运行时间: 40 ms, 内存: 0.0 MB
/*
* LeetCode题目: 倒水
*
* 题目思路:
* 给定一个整数数组`buckets`,其中每个元素表示一个水桶的容量。
* 需要找到在给定的最大倒水次数`pours`内,是否可以将所有的水桶都倒满。
*
* 解题步骤:
* 1. 使用Stream对水桶容量数组`buckets`进行排序。
* 2. 使用Stream计算倒水总容量`totalCapacity`。
* 3. 通过最大倒水次数`pours`来判断是否能满足所有水桶倒满。
*
*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class WaterPouringStream {
public boolean canFillAllBuckets(int[] buckets, int pours) {
int totalCapacity = Arrays.stream(buckets) // 步骤1: 使用Stream对水桶容量数组进行排序
.sorted()
.sum(); // 步骤2: 使用Stream计算倒水总容量
return pours >= totalCapacity; // 步骤3: 判断最大倒水次数是否满足
}
public static void main(String[] args) {
WaterPouringStream wp = new WaterPouringStream();
int[] buckets = {2, 3, 5};
int pours = 10;
boolean result = wp.canFillAllBuckets(buckets, pours);
System.out.println(result); // 输出: true
}
}
解释
方法:
该题解采用了模拟倒水的过程,使用了两个单调栈分别记录倒水过程中左右两侧的可倒水的低洼位置。具体思路如下:
1. 首先利用 findLeft 和 findRight 两个函数分别找出初始位置 K 左右两侧的所有可倒水的低洼位置,并分别存入 leftStack 和 rightStack 中。
2. 开始模拟倒水过程,总共倒 V 次水:
- 如果 leftStack 非空,则将水倒在 leftStack 的栈顶位置,并更新该位置的高度。如果该位置已经不再是低洼,则将其从 leftStack 中弹出。然后检查其左侧相邻位置是否因为高度改变而成为新的低洼,如果是则将其加入 leftStack。
- 如果 leftStack 为空但 rightStack 非空,则将水倒在 rightStack 的栈顶位置,并更新该位置的高度。如果该位置已经不再是低洼,则将其从 rightStack 中弹出。然后检查其右侧相邻位置是否因为高度改变而成为新的低洼,如果是则将其加入 rightStack。
- 如果 leftStack 和 rightStack 均为空,则将水倒在初始位置 K 上,并更新 K 位置的高度。然后重新调用 findLeft 和 findRight 函数更新 leftStack 和 rightStack。
3. 倒完 V 次水后,返回更新后的高度数组 heights 即可。
时间复杂度:
O(V*n)
空间复杂度:
O(n)
代码细节讲解
🦆
在模拟倒水的过程中,如果同时左右两侧栈均非空,你是如何决定优先倒水到左侧还是右侧的?
▷🦆
当左或右侧的单调栈为空时,你是如何确保继续倒水操作不会导致非最低点被选择的?
▷🦆
在更新高度信息后,你是如何判断并处理位置变为非低洼的情况?特别是在复杂的地形变化中。
▷🦆
当你说如果 '左右均无低洼位置,则将水倒在初始位置 K',这种情况下如何处理 K 位置周围可能产生的新低洼位置?
▷