贪心算法与盛雨水问题

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

欸?


这其中的关键在于:

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

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

相关推荐
XiaoLeisj28 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿2 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd2 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v2 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A3 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组