给定一个整数数组,每个元素代表一栋建筑物。例如:int buildings[] = {1, 4, 3, 2, 3, 1}
。
如果我用刷子水平绘制建筑物,我将使用多少个刷子?
我应该编写一个函数来返回这些笔触的数量。例如5
。
通过使用2个循环,我可以在运行时O(n^2)
轻松地做到这一点。
在每个建筑物的楼层上运行的外部循环(根据最高建筑物)。
内部循环在从0
到n
的数组上运行,并比较两个近距离之间的高度差(0
或1
)元素。
如何在O(n)
时间和O(n)
的空间中做到这一点?
答案 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;
}