Disk Stacking
Disk Stacking
Category
Dynamic Programming
Difficulty
Hard
Problem Statement
Given a list of disks where each disk is represented by [width, depth, height], stack them to maximize total height. A disk can only be placed on top of another if it is strictly smaller in all three dimensions (width, depth, and height) than the disk below it. Return the stacked disks in order from bottom to top.
Intuition
This is a variant of the Longest Increasing Subsequence (LIS) problem in three dimensions. If we sort the disks by one dimension (e.g., height), then for each disk we only need to look at previously considered disks to check if they can sit below it. The optimal stack ending at disk i is the best stack ending at some valid predecessor j plus disk i itself.
Approach
- Sort disks by height (ascending).
- Create an array
heightswhereheights[i]is the maximum stack height ending with diski, initialized to each disk's own height. - Create a
predecessorsarray to track which disk comes before each disk in the optimal stack. - For each disk
i, iterate over all previous disksj < i:- If disk
jis strictly smaller in all three dimensions than diski, andheights[j] + disk[i].height > heights[i], updateheights[i]and recordjas the predecessor ofi.
- If disk
- Find the index with the maximum value in
heights. - Backtrack through
predecessorsto build the stack.
Pseudocode
function diskStacking(disks):
sort disks by height ascending
heights = [disk[2] for disk in disks] // each disk's own height
predecessors = [-1, -1, ..., -1] // length n
for i from 1 to n-1:
for j from 0 to i-1:
if disks[j][0] < disks[i][0] and
disks[j][1] < disks[i][1] and
disks[j][2] < disks[i][2]:
if heights[j] + disks[i][2] > heights[i]:
heights[i] = heights[j] + disks[i][2]
predecessors[i] = j
maxIdx = index of max value in heights
stack = []
while maxIdx != -1:
stack.append(disks[maxIdx])
maxIdx = predecessors[maxIdx]
return reverse(stack)
Time & Space Complexity
| Measure | Complexity | Justification |
|---|---|---|
| Time | O(n^2) | For each disk, we compare against all previous disks |
| Space | O(n) | Arrays for heights and predecessors |
Key Insights
- Sorting by one dimension reduces the problem to a 1D LIS-style DP where only "backward" comparisons are needed.
- Strict inequality in all three dimensions is required — not just two.
- The choice of which dimension to sort by does not affect correctness, but sorting by height is natural since we are maximizing total height.
- Unlike classic LIS, there is no O(n log n) optimization here because the ordering is partial (three dimensions), not total.
Edge Cases
- Single disk: the answer is just that disk.
- No disk can be placed on another: the tallest individual disk is the answer.
- All disks are identical: only one disk can be in the stack.
- Disks that match in one or two dimensions but not all three: they cannot be stacked (strict inequality required on every dimension).