啥是盛雨水问题?给个图就熟悉了
欸?
这其中的关键在于:
-
容量2D化就是长 * 宽
-
木桶效应:宽取决于短板。
那我们来分析,怎么样能达到最佳的结果呢?穷举一下所有可能性不就好了?每两个板子构成一个组合,挨个计算一遍,找个最大值!
欸?不错!是个思路。
但!我们看看是不是需要每两个之间都得计算呢?假如,我们把初始位置设置为最边边的两根板子上(后面会说为什么这么初始化)。
计算当前的容量,然后换种可能性。怎么换?换i还是换j?
-
换i,按当前的状态看,i是较短的那个,因为 3 < 4,所以i是较短的那个。当i右移的时候,遇到的新的板子,可能比当前高,也可能变矮。如果变高,容量变化不定。如果变矮,新的容量会变小。
-
换j,按当前的状态看,j是较长的那个,当j左移的时候,遇到的新的板子,可能比当前高,也可能变矮。如果变高,那么新的容量一定变小。如果变矮,新的容量更会变小。
所以从上面来看,换i是最合适的。其实是每次换一个短板,这样就找到一个让容量变大的可能性。
java
/* 最大容量:贪心 */
int maxCapacity(int[] ht) {
// 初始化 i, j,使其分列数组两端
int i = 0, j = ht.length - 1;
// 初始最大容量为 0
int res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
int cap = Math.min(ht[i], ht[j]) * (j - i);
res = Math.max(res, cap);
// 向内移动短板
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}
所以,为什么从两边初始化?不是从一侧,或者中间?
其实这里暗含了一个变量,如果初始化为两侧,无论移动哪个(i + 1 / j - 1),长肯定是变短的,
这就把产生容量变化的影响因素变成了板子的高度。否则你需要考虑是长度导致的容量变化还是板子的高度导致的容量变化