题目:


题目过程:

执行结果:

步骤:
一、
1、数组下标 i 就是柱子的 x 坐标;height i 就是柱子高度。
2、选两根柱子:左柱子下标i,右柱子下标j,必须满足 j>i。
3、容器装水:不能倾斜。水不会超过矮的那根柱子。
所以水的高度 = min (height i, height j )
容器宽度 = 两根柱子横坐标差:j - i
面积(水量)= 宽度 × 水高度 = (j‑i) * min (height i, height j)
4、目标:遍历所有 i,j 组合,算出所有可能面积,找出最大值。
5、示例 : 输入:height = 1,8,6,2,5,4,8,3,7,输出答案 49。
二、思考暴力解法是否可以
i从第 0 根柱子开始,固定 i。
j 从 i+1 开始,j 在 i 右边。
每一组 (i,j) 算面积,记录最大的值。
但这个是有问题的,如果n很大,比如n=1e5,双层循环要运行很多次,所以不适合。
三、思考去优化
利用面积公式:面积=宽度xmin(左高,右高)
初始最大宽度是什么?最左边柱子 和 最右边柱子,此时宽度 = n‑1,宽度直接拉满。
那我设置两个指针:left 在最左边 0,right 在最右边 heightSize‑1。
这就是初始最大宽度。
两个选择:
1、移动高的柱子 right--:新宽度会变小。短板依旧还是 left=2。新面积 =(更小宽度) ×2。面积一定比现在更小!这个方向
2、不可能得到更大值,完全不用算。
移动矮的柱子 left++:虽然宽度变小,但是新的 left 高度有可能变大!min 值有可能提升,才有机会得到更大面积。
所以:每次移动高度更加小的那一侧的指针。但如果高度相等两边都可以。
手动验证:
样例数组:1,8,6,2,5,4,8,3,7,n=9
left=0,right=8,max=0
1、left=0 (h=1),right=8 (h=7)
width=8‑0=8;h=min (1,7)=1;area=8*1=8。max=8 左边矮,left++ → left=1
2、left=1 (h=8), right=8 (h=7)
width=7;h=min (8,7)=7;area=7*7=49。max=49 右边矮,right-- → right=7
3、left=1 (h=8), right=7 (h=3) width=6;h=3;area=18。max 不变。 右边矮 right-- → right=6
等等......
五、翻译成代码,进行测试
注意:不要把 cur_h(装水高度)拿去做指针判断!判断移动指针要用原始 height 值,不是 min 之后的值。