在 Java 中,不考虑后续的崩溃:
public static int collapse(int[] buildings) {
int i, maxDamage, index, currentDamage;
// do not consider the last building, it will cause only its own fall
maxDamage = 1;
index = buildings.length - 1;
for(i = buildings.length - 1; i >= 0; i--) {
// update maximum damage as the mimimum value between the building[i] (the height of the building at index i) and the remaining number of elements from i to the end of the array
currentDamage = Math.min(buildings[i], buildings.length - i);
System.out.println(currentDamage);
if(currentDamage > maxDamage) {
maxDamage = currentDamage;
index = i;
}
}
return index;
}
我的最终解决方案与接受的解决方案不同,顺便说一下,我并没有完全理解。这个想法是从最右边的位置开始计算当前索引将倒塌的建筑物的数量。
index: 7 6 5 4 3 2 1 0
height: 1 3 1 2 4 1 3 2
damage: 1 2 1 2 4 1 3 2
然后我只是从最右边的位置开始累积总和。我将当前位置倒塌的建筑物数量添加到倒塌的建筑物数量上,从右边的下一栋建筑物凝视直到最后都没有倒塌。
index: 7 6 5 4 3 2 1 0
height: 1 3 1 2 4 1 3 2
damage: 1 2 1 2 5 1 7 8
最后,我只返回最大伤害的索引。
该解决方案运行O(n)
但使用了额外的O(n)
空间。
下一个代码是完整版本(也适用于后续折叠):
public static int collapse(int[] buildings) {
int i, maxIndex, max;
int damage[] = new int[buildings.length];
for(i = buildings.length - 1; i >= 0; i--) {
// compute damage for each position
damage[i] = Math.min(buildings[i], buildings.length - i);
}
for(i = buildings.length - 1; i >= 0; i--) {
// update total accumulated damage for each position
if(damage[i] > 1) {
if(damage[i] + i - 1 < buildings.length && i != (i + damage[i] - 1) ) {
damage[i] += damage[i + damage[i] - 1] - 1;
}
}
}
max = damage[0];
maxIndex = 0;
for(i = 1; i < buildings.length; i++) {
// find the maximum damage
if(damage[i] > max) {
max = damage[i];
maxIndex = i;
}
}
return maxIndex;
}