如何计算绘制一组建筑物需要多少水平笔触?

时间:2019-05-30 07:23:22

标签: arrays algorithm

给定一个整数数组,每个元素代表一栋建筑物。例如:int buildings[] = {1, 4, 3, 2, 3, 1}

如果我用刷子水平绘制建筑物,我将使用多少个刷子?

我应该编写一个函数来返回这些笔触的数量。例如5

enter image description here

通过使用2个循环,我可以在运行时O(n^2)轻松地做到这一点。

  • 在每个建筑物的楼层上运行的外部循环(根据最高建筑物)。

  • 内部循环在从0n的数组上运行,并比较两个近距离之间的高度差(01)元素。

如何在O(n)时间和O(n)的空间中做到这一点?

4 个答案:

答案 0 :(得分:13)

每当笔划高度从左向右增加时,笔划就会开始,当笔划减小时,笔划就会结束。您只需要查看它增加的时间,因为如果您仅计算每个笔画的起点,您将获得笔画数。与其在内部循环中遍历高度水平,不如从前一个高度中减去一个高度水平即可得到差异。

使用伪代码:

int BrushCount(int[] buildings)
{
    int brushCount = 0;
    int prevHeight = 0;
    for(int i = 0; i < buildings.length; i++)
    {
        if(buildings[i] > prevHeight)
             brushCount = brushCount + (buildings[i] - prevHeight);
        prevHeight = buildings[i];
    }
    return brushCount;
}

以O(n)运行。

答案 1 :(得分:2)

打高尔夫球的代码:)(基于samgak出色的explanation。)

const f = A => A.reduce((a,b,i,A) => a + Math.max(0, b - A[i-1]));

console.log(f([1, 4, 3, 2, 3, 1]))
console.log(f([4, 1, 2, 1, 2, 2]))

答案 2 :(得分:1)

从数组末尾开始计数时,将最后一个元素用作结果的初始值,并将前一个与当前元素进行比较。

如果它们是相同的值,则结果加1;否则,结果加1。  如果前一个小于当前,则不执行任何操作;  如果前一个大于当前,则result =结果+上一个当前

int i=sizeof buildings;
int t=buildings[i]; 
while(i>0){
  if(buildings[i-1]-buildings[i]>0) t+=(buildings[i-1]-buildings[i]);
  else if(buildings[i-1]-buildings[i]==0) ++t;
  --i;
}
return t;

答案 3 :(得分:0)

public static int brushCount(int[] buildings)
{
    int count=0;
    for(int i=0; i<=buildings.length-1; i++){
        if((i+1)<(buildings.length)){
            if(buildings[i]>buildings[i+1]){
                count += buildings[i]-buildings[i+1];
            }
        }else{
            count += buildings[i];
        } 
    }
    return count;
}