贪心算法与盛雨水问题

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

欸?


这其中的关键在于:

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

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

相关推荐
VertexGeek20 分钟前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz20 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
jiao_mrswang1 小时前
leetcode-18-四数之和
算法·leetcode·职场和发展
qystca1 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱1 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
今天吃饺子1 小时前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
是阿建吖!1 小时前
【优选算法】二分查找
c++·算法
王燕龙(大卫)2 小时前
leetcode 数组中第k个最大元素
算法·leetcode
不去幼儿园2 小时前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Mr_Xuhhh2 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法