计算阵列描述的工具可以包含的水量

时间:2018-02-22 13:13:25

标签: algorithm

有收集雨水的工具。该工具的横断面图由长度为n的数组描述。

例如: 对于这个数组{2,1,1,4,1,1,2,3},横断面图是: click here

我需要计算工具可以承受的水量,时间和地点O(n)的复杂程度。 。 对于上面的数组,它是7(灰色区域)。 click here

我的想法:

由于它是一个图形问题,我最初的想法是首先计算数组的最大值并将其乘以n。这是我需要减去的起始量。

例如在上面的数组中,我需要减去绿色区域和高度本身: click here

这就是我所困扰的地方,需要帮助才能达到所需的复杂程度。

注意:也许我过度思考并且有更好的方法来处理这个问题。但正如我所说,由于它是一个图形问题,我的第一个想法是寻求几何解决方案。

任何提示或提示都会受到欢迎。

2 个答案:

答案 0 :(得分:4)

位置i的水位较小:

  • 位置处的最大容器高度< = i;和
  • 位置处的最大容器高度> = i

使用两次通过阵列计算每个位置的这两个最大值,然后总结水位和容器高度之间的差异。

答案 1 :(得分:1)

这是一个类似于@MattTimmermans描述的算法的python实现。代码读起来像伪代码,所以我不认为需要额外的解释:

def _find_water_capacity(container):
    """returns the max water capacity as calculated from the left bank
       of the given container
    """
    water_levels = [0]
    current_left_bank = 0
    idx = 0

    while idx < len(container) - 1:
        current_left_bank = max(current_left_bank, container[idx])
        current_location_height = container[idx + 1]
        possible_water_level = current_left_bank - current_location_height

        if possible_water_level <= 0:
            water_levels.append(0)
        else:
            water_levels.append(possible_water_level)
        idx += 1

    return water_levels


def find_water_capacity(container):
    """returns the actual water capacity as the sum of the minimum between the
    left and right capacity for each position """
    to_left = _find_water_capacity(container[::-1])[::-1]  #reverse the result from _find_water_capacity of the reversed container.
    to_right = _find_water_capacity(container)
    return sum(min(left, right) for left, right in zip(to_left, to_right))


def test_find_water_capacity():
    container = []
    expected = 0
    assert find_water_capacity(container) == expected
    assert find_water_capacity(container[::-1]) == expected

    container = [1, 1, 1, 1, 1]
    expected = 0
    assert find_water_capacity(container) == expected
    assert find_water_capacity(container[::-1]) == expected

    container = [5, 4, 3, 2, 1]
    expected = 0
    assert find_water_capacity(container) == expected
    assert find_water_capacity(container[::-1]) == expected

    container = [2, 1, 1, 4, 1, 1, 2, 3]   # <--- the sample provided
    expected = 7
    assert find_water_capacity(container) == expected
    assert find_water_capacity(container[::-1]) == expected

    container = [4, 1, 1, 2, 1, 1, 3, 3, 3, 1, 2]
    expected = 10
    assert find_water_capacity(container) == expected
    assert find_water_capacity(container[::-1]) == expected

    container = [4, 5, 6, 7, 8, -10, 12, 11, 10, 9, 9]
    expected = 18
    assert find_water_capacity(container) == expected
    assert find_water_capacity(container[::-1]) == expected

    container = [2, 1, 5, 4, 3, 2, 1, 5, 1, 2]
    expected = 12
    assert find_water_capacity(container) == expected
    assert find_water_capacity(container[::-1]) == expected

    print("***all tests find_water_capacity passed***")


test_find_water_capacity()