当前位置: 首页 > 知识库问答 >
问题:

塔楼之间收集的水

桑博远
2023-03-14

我最近遇到了亚马逊提出的一个面试问题,我无法找到一个优化的算法来解决这个问题:

给定一个输入数组,每个元素表示线塔的高度。每个塔的宽度为1。开始下雨了。塔之间收集了多少水?

实例

Input: [1,5,3,7,2] , Output: 2 units
Explanation: 2 units of water collected between towers of height 5 and 7

   *
   *
 *w*
 *w*
 ***
 ****
*****

另一个例子

Input: [5,3,7,2,6,4,5,9,1,2] , Output: 14 units 
Explanation= 2 units of water collected between towers of height 5 and 7 +
             4 units of water collected between towers of height 7 and 6 + 
             1 units of water collected between towers of height 6 and 5 +
             2 units of water collected between towers of height 6 and 9 +
             4 units of water collected between towers of height 7 and 9 +
             1 units of water collected between towers of height 9 and 2.

起初我认为这可以通过库存跨度问题来解决(http://www.geeksforgeeks.org/the-stock-span-problem/)但我错了,所以如果有人能想出一个时间优化的算法来解决这个问题,那就太好了。

共有3个答案

马渊
2023-03-14

参考这个网站的代码,它非常简单明了http://learningarsenal.info/index.php/2015/08/21/amount-of-rain-water-collected-between-towers/

输入:[5,3,7,2,6,4,5,9,1,2],输出:14台

每座塔都可以将水保持在左边最高塔和右边最高塔之间的最小高度。

因此,我们需要计算每个塔楼左边的最高塔楼,同样地,也需要计算右边的塔楼。

在这里,我们将需要两个额外的阵列来保持任何塔楼(例如int leftMax[])左侧最高塔楼的高度,同样地,对于右侧塔楼(例如int rightMax[])。

第一步

我们对给定数组进行左传递(即int tower[]),并将保持一个临时最大值(例如int tempMax),以便在每次迭代中,将每个塔的高度与tempMax进行比较,如果当前塔的高度小于tempMax,则tempMax将设置为其左侧的最高塔,否则,当前塔的高度将被指定为左侧最高的塔,tempMax将用当前塔的高度更新,

第二步

我们将只按照步骤1中讨论的上述步骤来计算右侧的最高塔,但这一次是从右侧进行穿透阵列。

步骤3

每个塔能容纳的水量为-

(最高右塔楼与最高左塔楼之间的最小高度)-(塔楼高度)

何涵畅
2023-03-14

哈斯克尔有一个有效的解决方案

rainfall :: [Int] -> Int
rainfall xs = sum (zipWith (-) mins xs)
    where mins = zipWith min maxl maxr
          maxl = scanl1 max xs
          maxr = scanr1 max xs

它使用了其他答案中提到的相同的双遍扫描算法。

夏飞掣
2023-03-14

一旦水落下,每个位置的水位将等于左边最高的塔和右边最高的塔中较小的一个。

通过向右扫描,找到每个位置左侧的最高塔。然后通过向左扫描,找到每个位置右侧的最高塔。然后在每个位置取最小值,并将它们全部相加。

这样的事情应该奏效:

int tow[N]; // nonnegative tower heights
int hl[N] = {0}, hr[N] = {0}; // highest-left and highest-right
for (int i = 0; i < n; i++) hl[i] = max(tow[i], (i!=0)?hl[i-1]:0);
for (int i = n-1; i >= 0; i--) hr[i] = max(tow[i],i<(n-1) ? hr[i+1]:0);
int ans = 0;
for (int i = 0; i < n; i++) ans += min(hl[i], hr[i]) - tow[i];
 类似资料:
  • 有什么方法可以从InboundAdapter到OutboundAdapter收集这样的度量: 每秒的消息量; 邮件总数; 分钟通过流传递时间; 通过流的最大传输时间; 通过流传递的平均时间; 错误消息的数量; 处理邮件的持续时间; 我尝试了使用MessageChannelMetrics提出的解决方案: https://docs.Spring.io/Spring-Integration/refere

  • 从方法1开始,我一直在研究Leetcode问题的不同算法。如果阵列值是墙的高度,则需要计算总水域面积(列宽=1)。 第一种方法是找出每根立柱左右两侧最大墙高的最小高度,如果立柱高度小于最小值,则向给定立柱顶部加水。取最小值,因为这是收集的水能够达到的最高值。要计算每侧的最大值,需要对左侧和右侧进行n-1次遍历。 我用Python编写代码,但下面是根据Leetcode上给出的解决方案用C编写的代码。

  • 我试图了解两者之间是否有任何重大差异。在查看示例时,我注意到它使用了完全相同的二进制和arg(https://github.com/open-telemetry/opentelemetry-collector/blob/main/examples/demo/docker-compose.yaml). 唯一的区别是配置文件在导出器/接收器方面有所不同。因此,唯一的区别是使用什么endpoint来收集

  • 本文向大家介绍Java中的集合与集合之间的区别,包括了Java中的集合与集合之间的区别的使用技巧和注意事项,需要的朋友参考一下 Java收集框架用于操纵对象的收集。收集框架包含多个包装器类,便利类,用于传统实现的类,例如vector和Hashtable,收集接口等。     集合是Java集合框架中的接口。它分为两部分- Java util集合-它包含诸如Set,queue,List等的类。 Ja

  • 我试图在两个 kubernetes 集群中的两个应用程序之间获取 mTLS,而没有 Istio 的方式(使用其入口网关),我想知道以下内容是否有效(对于 Istio,对于 Likerd,对于 Consul...)。 假设我们有一个带有应用程序A. A的k8s集群A和一个带有应用程序B. B的集群B。我希望它们与mTLS通信。 集群A为nginx入口控制器提供了letsEncrypt证书,并为其应用

  • 从技术上讲,< code>cron、< code>crontab和< code>cronjob之间有什么区别? 从我能收集到的信息来看,是服务器上的实用程序,是一个包含时间间隔和命令的文件,是实际的命令(或包含命令的文件/脚本)。 这是正确的吗?