堆箱子
难度:
标签:
题目描述
You have a stack of n boxes, with widths wi, depths di, and heights hi. The boxes cannot be rotated and can only be stacked on top of one another if each box in the stack is strictly larger than the box above it in width, height, and depth. Implement a method to compute the height of the tallest possible stack. The height of a stack is the sum of the heights of each box.
The input use [wi, di, hi]
to represents each box.
Example1:
Input: box = [[1, 1, 1], [2, 2, 2], [3, 3, 3]] Output: 6
Example2:
Input: box = [[1, 1, 1], [2, 3, 4], [2, 6, 7], [3, 4, 5]] Output: 10
Note:
box.length <= 3000
代码结果
运行时间: 417 ms, 内存: 16.8 MB
/*
* 思路:
* 1. 首先,对箱子按照宽度、深度、高度进行排序。
* 2. 然后,使用动态规划的方法,dp[i]表示以第i个箱子为最顶端箱子时的最大堆叠高度。
* 3. 对于每个箱子,计算其最大堆叠高度时,要检查所有比它宽、深、高都小的箱子,更新最大高度。
* 4. 最终结果为所有dp值中的最大值。
*/
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
public class BoxStackingStream {
public int pileBox(int[][] box) {
Arrays.sort(box, Comparator.<int[]>comparingInt(a -> a[0])
.thenComparingInt(a -> a[1])
.thenComparingInt(a -> a[2]));
int n = box.length;
int[] dp = new int[n];
IntStream.range(0, n).forEach(i -> dp[i] = box[i][2]);
IntStream.range(0, n).forEach(i ->
IntStream.range(0, i).forEach(j -> {
if (box[j][0] < box[i][0] && box[j][1] < box[i][1] && box[j][2] < box[i][2]) {
dp[i] = Math.max(dp[i], dp[j] + box[i][2]);
}
})
);
return IntStream.of(dp).max().orElse(0);
}
public static void main(String[] args) {
BoxStackingStream solution = new BoxStackingStream();
int[][] box1 = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
int[][] box2 = {{1, 1, 1}, {2, 3, 4}, {2, 6, 7}, {3, 4, 5}};
System.out.println(solution.pileBox(box1)); // 输出6
System.out.println(solution.pileBox(box2)); // 输出10
}
}
解释
方法:
此题解采用动态规划的思想。首先对箱子进行排序,便于后续比较。之后,定义一个数组 h,其中 h[i] 表示以第 i 个箱子为顶部箱子时能达到的最大高度。对于每个箱子 i,遍历在其之前的所有箱子 j,检查是否可以把箱子 j 堆放在箱子 i 下面(即满足 wi > wj, di > dj, hi > hj 的条件)。如果可以,则计算如果以箱子 j 为基底时的总高度,更新 h[i]。最终,遍历所有的 h[i],找到最大值即为答案。
时间复杂度:
O(n^2)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在对箱子进行排序时没有指定排序的具体规则(如按宽度、深度或高度排序)?排序的规则会如何影响算法的效果?
▷🦆
动态规划中使用的数组 h[i] 表示的是以第 i 个箱子为顶部时的最大高度,这个定义是否意味着每个箱子都必须使用,还是说它们可以被跳过?
▷🦆
在内层循环中,条件 wj < wi, dj < di, hj < hi 用来判断箱子 j 是否可以放在箱子 i 下面。这里的 '小于' 条件是否意味着箱体尺寸必须严格递减?如果是,这是否限制了某些可能的有效堆叠方式?
▷