关于《盛水最多的容器》问题的思考

力扣 #11 问题里,我们可能会陷入这样的误区:装水的容器内部(即两侧的挡板之间)不能存在一个高于水平面的挡板。其实应该理解为,选中两块板,然后拆掉中间的所有板,求能放入由两者、X 轴所限定区域的最大矩形面积。

这个面积的表示可以用数学符号来表示,下面我们将这个问题数学符号化。设每个挡板的高度为 Hn,其中 0nN1N 是挡板的数量。任意两块挡板,设序号为 ab 且满足 0abN1,则由这两块挡板和 X 轴限定的最大矩形面积可以表示为:

area=(ba)×min{Ha,Hb}

于是,问题转换为:设 0a<bN1 ,求 area 最大值。

刚看到这个问题的时候,我们很难不考虑遍历所有的可能性。这个方法一定可以找出最终的结果,但是却显得非常不优雅且低效。假设我们从 0 号挡板开始判断,那么每一个挡板都需要依次与编号比它大的所有挡板进行计算比较。所以可以用数学符号表示每一个挡板的比较次数 Cn 为:

C0=N1C1=N2CN3=2CN2=1

也就是:

C=0N1Cn=(N1)+(N2)++2+1=N×(N1)2=O(N2)

即:把单次计算和比较看作一次原子操作,那么整个遍历过程的时间复杂度为 O(N2)。显然这样的方式不是我们想要的,我们需要思考一种复杂度更低的方式。

不妨考虑这样一种情况,如果我们已经知道最大值就在某个范围内,如何选择下一个值来进行比较?比如我们在某一次判断过程中,已知 Ha<Hb 。那么下一步就要判断需要判定 [a,b1] 还是 [a+1,b] 了。

area=(ba)×min{Ha,Hb}=(ba)×Ha

方案一,考虑 [a,b1],此时分两种情况:

情况 A,若 Hb1Hb

area=(b1a)×min{Ha,Hb1}(b1a)×min{Ha,Hb}<(ba)×min{Ha,Hb}=(ba)×Ha

情况 B,若 Hb1>Hb

area=(b1a)×min{Ha,Hb1}=(b1a)×Ha<(ba)×Ha

可见,从 b 位置的挡板切换到 b1 时,一定有 area<area

方案二,考虑 [a+1,b],此时分两种情况:

情况 A,若 HaHa+1

area=(ba1)×min{Ha+1,Hb}=(ba1)×min{Ha,Hb}<(ba)×Ha

情况 B,若 Ha<Ha+1

area=(ba1)×min{Ha+1,Hb}

可见:

  • 从较短的一边 a 位置的挡板切换到 a+1 时,如果 HaHa+1 ,则 area<area 一定成立;
  • Ha<Ha+1 时可能出现 area>area 的情况。

同理,若 HaHb,上述结论仍然成立。

综上,如果已知最大值在范围 [a,b],那么想要找到下一个潜在的更大的值,必须要将两端较短的一个向着另一边移动。在这个理论之下,我们可以摒弃很多无用的检查,可以一直重复上述移动过程直到最终两个端点挨到一起。这样一来,每一个高度值只会被判断一次,整体的时间复杂度就是 O(N)

  那阵东风  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示