贪心算法与盛雨水问题

啥是盛雨水问题?给个图就熟悉了

欸?


这其中的关键在于:

  1. 容量2D化就是长 * 宽

  2. 木桶效应:宽取决于短板

那我们来分析,怎么样能达到最佳的结果呢?穷举一下所有可能性不就好了?每两个板子构成一个组合,挨个计算一遍,找个最大值!

欸?不错!是个思路。


但!我们看看是不是需要每两个之间都得计算呢?假如,我们把初始位置设置为最边边的两根板子上(后面会说为什么这么初始化)。

计算当前的容量,然后换种可能性。怎么换?换i还是换j?

  1. 换i,按当前的状态看,i是较短的那个,因为 3 < 4,所以i是较短的那个。当i右移的时候,遇到的新的板子,可能比当前高,也可能变矮。如果变,容量变化不定。如果变,新的容量会变小。

  2. 换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),长肯定是变短的

这就把产生容量变化的影响因素变成了板子的高度。否则你需要考虑是长度导致的容量变化还是板子的高度导致的容量变化

相关推荐
JieE21221 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack201 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树1 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050732 天前
(一)小红的数组操作
算法·编程语言
怕浪猫2 天前
Electron 系列文章封面图
算法·架构·前端框架