【问题标题】:Find Maximun area on Array查找阵列上的最大面积
【发布时间】:2018-11-16 17:36:47
【问题描述】:

我正在使用 Scala 中的应用程序 Data Structures 进行练习,我在数组上编写了第二个问题,如下所示:

/**
   * Given n non-negative integers a1, a2, ..., an, where each represents a
   * point at coordinate (i, ai), n vertical lines are drawn such that
   * the two endpoints of line i is at (i, ai) and (i, 0). 
   * 
   * Find two lines, which together with x-axis forms a container such
   * that the container contains the most water.
   *
   * Efficiency: O(n)
   *
   * @param a Array of line heights
   * @return Maximum area
   */
  def maxArea(a: Array[Int]): Int = {
    @tailrec
    def go(l: Int, r: Int)(max: Int): Int = {
      if (l >= r) max
      else {
        val currArea = math.min(a(l), a(r)) * (r - l)
        val area = math.max(max, currArea)
        log debug s"Current area for $l and $r is $currArea"
        log debug s"Max area till now is $area"
        if (a(l) < a(r)) go(l + 1, r)(area)
        else go(l, r - 1)(area)
      }
    }
    go(0, a.size - 1)(0)
}

我想知道是否有更好的替代方法来编写递归函数作为遍历数组的一种方式,因为someone once told me将递归称为函数式编程的 GOTO

您可以在GitHub查看完整的源代码

提前谢谢你。

【问题讨论】:

标签: arrays scala performance data-structures


【解决方案1】:

这是一种无需递归即可实现算法的方法(并不是说我实际上认为递归存在任何固有的错误)。

def maxArea2(a: Array[Int]): Int = {
  Stream.iterate(0 -> a){ case (_, arr) =>
    if (arr.length < 2) -1 -> arr
    else {
      val (lft, rght) = (arr.head, arr.last)
      val area = (lft min rght) * (arr.length - 1)
      if (lft <= rght) area -> arr.dropWhile(_ <= lft)
      else             area -> arr.reverse.dropWhile(_ <= rght)
    }
  }.takeWhile(_._1 >= 0).maxBy(_._1)._1
}

这个想法是懒惰地迭代,只获取(即实现)你需要的那些。

您会注意到,这会减少迭代和计算面积的次数,因为它丢弃的值无法超过当前的面积计算。

【讨论】:

  • 谢谢!,看来这种方法会更有效?
猜你喜欢
  • 2012-10-17
  • 2013-07-30
  • 2020-10-17
  • 1970-01-01
  • 2018-03-09
  • 1970-01-01
  • 2021-11-26
  • 2020-08-30
  • 1970-01-01
相关资源
最近更新 更多