我们有N
个框。每个盒子都有3个参数:宽度,长度,高度。
我需要编写一个函数,使用此框生成最高的塔。 函数必须遵守以下规则:底部框的所有参数都应大于其上方的框。
假设我们有一个描述为int数组{width, length, height} -> {1, 2, 5}
的框,然后:
输入:boxes = {{2, 2, 3}, {1, 1, 1}, {3, 3, 3}, {4, 5, 4}, {7, 7, 1}}
输出:8
起{4, 5, 4} greater than {2, 2, 3} greater than {1, 1, 1}
我找到了一种我不明白的解决方案。
void sortArrDesc(int[][] array) {
Arrays.sort(array, new java.util.Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return -1 * Integer.compare(a[2], b[2]);
}
});
}
boolean canPlaceOnTop(int prevBoxIndex, int currBoxIndex, int[][] boxes) {
if (prevBoxIndex == -1) return true;
int[] bottomBox = boxes[prevBoxIndex];
int[] topBox = boxes[currBoxIndex];
return (bottomBox[0] > topBox[0] &&
bottomBox[1] > topBox[1] &&
bottomBox[2] > topBox[2]);
}
int getHighestTower(int prevBoxIndex, int currBoxIndex, int[][] boxes) {
if (currBoxIndex == boxes.length) return 0;
int nextBoxIndex = currBoxIndex + 1;
int heightWithCurrBox = 0;
if (canPlaceOnTop(prevBoxIndex, currBoxIndex, boxes)) {
int currentBoxHeight = boxes[currBoxIndex][2];
int heightNextBox = getHighestTower(currBoxIndex, nextBoxIndex, boxes);
heightWithCurrBox = heightNextBox + currentBoxHeight;
}
int heightWithoutCurrBox =
getHighestTower(prevBoxIndex, nextBoxIndex, boxes);
return Math.max(heightWithCurrBox, heightWithoutCurrBox);
}
int getHighestTower(int[][] boxes) {
sortArrDesc(boxes);
return getHighestTower(-1, 0, boxes);
}
我不知道getHighestTower
函数到底能做什么。
我的意思是,例如,当我调用函数Math.sqrt(5)
时,我知道我的平方根为5。但是在这里,在getHighestTower
函数中发生了奇怪的事情。
很明显,呼叫getHighestTower(-1, 0, boxes)
将返回最高的塔。
但是!当我们进行递归调用时,我不明白它们的含义。
getHighestTower(prevBoxIndex, nextBoxIndex, boxes)
这行是什么意思?
该调用似乎应该从nextBox
返回最大可能的高度,但是为什么我们需要使用prevBoxIndex
?
此外,此调用getHighestTower(currBoxIndex, nextBoxIndex, boxes);
看起来也一样,但是我们使用prevBoxIndex
而不是currBoxIndex
,为什么呢?
P.S。我已经找到了这个question,但是其中没有任何有用的信息。
答案 0 :(得分:0)
这个问题可以这样解决:
按高度对框进行排序。
然后的问题是寻找高度总和最大的递增子序列-这里的“递增”表示:
currLength > prevLength && currWidth > prevWidth && currHeight > prevHeight
对于输入{{2, 2, 3}, {1, 1, 1}, {3, 3, 3}, {4, 5, 4}, {7, 7, 1}}
让我们说按高度数组排序的是:
{7,7,1}, {1,1,1}, {2,2,3}, {3,3,3}, {4,5,4}
则具有上述标准的递增子序列为
{1,1,1}, {3,3,3}, {4,5,4}
那么高度为1 + 3 + 4 = 8
。
为什么首先需要按高度排序? 因为,假设输入为
{{4,5,4}, {2,2,3}, {1,1,1}, {3,3,3}, {7,7,1}}
并且不按高度排序,则按上述标准增加的子序列将产生
{1,1,1}, {3,3,3}
它给出的答案为1 + 3 = 4
,这不是最佳选择。
Java代码:
private static int getHeighestTower( int[][] x ) {
Arrays.sort( x, new Comparator<int[]>() {
@Override
public int compare( int[] a, int[] b ) {
return a[2] - b[2];
}
});
int[] L = new int[x.length];
Arrays.fill(L,1);
int max = 0;
int h = 0;
int hi = 0;
for ( int i = 0; i < x.length; i++ ) {
hi = x[i][2];
int lastAdded = 0;
for ( int j = 0; j < i; j++ ) {
if ( aBiggerThanB(x[i], x[j]) ) {
if ( L[i] < 1 + L[j] ) {
L[i] = 1 + L[j];
hi += x[j][2];
lastAdded = x[j][2];
} else if ( L[i] == 1 + L[j] ) {
hi = Math.max( hi, hi - lastAdded + x[j][2]);
}
}
}
h = Math.max( h, hi);
max = Math.max( max, L[i] );
}
return h;
}
private static boolean aBiggerThanB( int[] a, int[] b ) {
return a[0] > b[0] && a[1] > b[1] && a[2] > b[2];
}