Given n
cuboids
where the dimensions of the ith
cuboid is cuboids[i] = [widthi, lengthi, heighti]
(0-indexed). Choose a subset of cuboids
and place them on each other.
You can place cuboid i
on cuboid j
if widthi <= widthj
and lengthi <= lengthj
and heighti <= heightj
. You can rearrange any cuboid's dimensions by rotating it to put it on another cuboid.
Return the maximum height of the stacked cuboids
.
Example 1:
Input: cuboids = [[50,45,20],[95,37,53],[45,23,12]] Output: 190 Explanation: Cuboid 1 is placed on the bottom with the 53x37 side facing down with height 95. Cuboid 0 is placed next with the 45x20 side facing down with height 50. Cuboid 2 is placed next with the 23x12 side facing down with height 45. The total height is 95 + 50 + 45 = 190.
Example 2:
Input: cuboids = [[38,25,45],[76,35,3]] Output: 76 Explanation: You can't place any of the cuboids on the other. We choose cuboid 1 and rotate it so that the 35x3 side is facing down and its height is 76.
Example 3:
Input: cuboids = [[7,11,17],[7,17,11],[11,7,17],[11,17,7],[17,7,11],[17,11,7]] Output: 102 Explanation: After rearranging the cuboids, you can see that all cuboids have the same dimension. You can place the 11x7 side down on all cuboids so their heights are 17. The maximum height of stacked cuboids is 6 * 17 = 102.
Constraints:
n == cuboids.length
1 <= n <= 100
1 <= widthi, lengthi, heighti <= 100
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
Imagine you're trying to build the tallest tower possible with a set of blocks. The brute force method means we try every single possible combination of stacking the blocks to see which one results in the highest tower. This involves exploring all the different orders and orientations in which we can place the blocks.
Here's how the algorithm would work step-by-step:
def max_height_by_stacking_cuboids_brute_force(cuboids):
max_tower_height = 0
number_of_cuboids = len(cuboids)
for i in range(number_of_cuboids):
# Consider each cuboid as the base
for rotation in get_rotations(cuboids[i]):
current_tower_height = rotation[2]
current_stack = [rotation]
unused_cuboids = list(range(number_of_cuboids))
unused_cuboids.remove(i)
max_tower_height = max(max_tower_height,
build_tower(
current_stack,
unused_cuboids,
cuboids,
current_tower_height
))
return max_tower_height
def build_tower(current_stack, unused_cuboids, cuboids, current_tower_height):
max_height = current_tower_height
if not unused_cuboids:
return max_height
for cuboid_index in unused_cuboids:
# Try to place cuboid on top of current stack
for rotation in get_rotations(cuboids[cuboid_index]):
if can_place(rotation, current_stack[-1]):
# If the cuboid can be placed, add it to the stack
new_stack = current_stack + [rotation]
new_unused_cuboids = list(unused_cuboids)
new_unused_cuboids.remove(cuboid_index)
new_tower_height = current_tower_height + rotation[2]
# Recursively build the tower further
max_height = max(max_height,
build_tower(
new_stack,
new_unused_cuboids,
cuboids,
new_tower_height
))
return max_height
def get_rotations(cuboid):
rotations = []
rotations.append(tuple(sorted(cuboid)))
return rotations
def can_place(top_cuboid, bottom_cuboid):
# Check if all dimensions of top are <= bottom
return all(top_cuboid[i] <= bottom_cuboid[i] for i in range(3))
To find the maximum height of stacked cuboids, we need to cleverly arrange them so that taller cuboids are always below smaller ones. This approach involves first organizing each cuboid's dimensions and then sorting all cuboids to build the tallest possible stack from the bottom up.
Here's how the algorithm would work step-by-step:
def max_height(cuboids):
for cuboid in cuboids:
cuboid.sort()
# Sort cuboids to prioritize larger bases.
cuboids.sort(key=lambda x: (x[0], x[1], x[2]), reverse=True)
number_of_cuboids = len(cuboids)
maximum_heights = [0] * number_of_cuboids
for i in range(number_of_cuboids):
maximum_heights[i] = cuboids[i][2]
# Find the maximum height by including current cuboid.
for j in range(i):
if cuboids[j][0] >= cuboids[i][0] and \
cuboids[j][1] >= cuboids[i][1] and \
cuboids[j][2] >= cuboids[i][2]:
maximum_heights[i] = max(maximum_heights[i], maximum_heights[j] + cuboids[i][2])
# Find the overall maximum height.
maximum_overall_height = 0
for height in maximum_heights:
maximum_overall_height = max(maximum_overall_height, height)
return maximum_overall_height
Case | How to Handle |
---|---|
Empty input cuboids array | Return 0 if the input array is empty, as no height can be formed. |
Single cuboid input | Return the height of the single cuboid if the input only contains one cuboid, as it's already the maximum possible height. |
Cuboids with dimensions of zero | Filter out any cuboids with any dimension being zero, as they cannot contribute to the height. |
Large number of cuboids | The dynamic programming approach should scale reasonably, but consider potential memory limitations for very large inputs and optimize accordingly. |
Cuboids with identical dimensions | The algorithm should correctly handle identical cuboids by considering all valid stacking permutations, potentially using memoization to avoid redundant calculations. |
Integer overflow when summing heights | Use a data type that can accommodate large sums of heights (e.g., long) to prevent integer overflow. |
No valid stacking order exists | The algorithm should return 0 if no cuboid can be stacked on top of another according to the problem constraints. |
Cuboid dimensions are very large integers | Ensure that comparisons between cuboid dimensions don't result in integer overflow or unexpected behavior by using appropriate data types (e.g., long). |