[Algorithm] Disk height (DP + back tracking)
You're given a non-empty array of arrays where each subarray holds three integers and represents a disk. These integers denote each disk's width, depth, and height, respectively. Your goal is to stack up the disks and to maximize the total height of the stack. A disk must have a strictly smaller width, depth, and height than any other disk below it.
Write a function that returns an array of the disks in the final stack, starting with the top disk and ending with the bottom disk. Note that you can't rotate disks; in other words, the integers in each subarray must represent [width, depth, height] at all times.
You can assume that there will only be one stack with the greatest total height.
Sample Input
disks = [[2, 1, 2], [3, 2, 3], [2, 2, 8], [2, 3, 4], [1, 3, 1], [4, 4, 5]]
Sample Output
[[2, 1, 2], [3, 2, 3], [4, 4, 5]]
// 10 (2 + 3 + 5) is the tallest height we can get by
// stacking disks following the rules laid out above.
function diskStacking(disks) {
// sort the disk by height
const sortedDisks = disks.sort(([,,ha], [,,hb]) => ha - hb)
// store current max height for each index
let maxHeights = sortedDisks.map(([w,d,h]) => h)
let maxHeightIndex = maxHeights.length - 1
let maxHeight = maxHeights[maxHeightIndex]
// store the previous stacked index for each index for back tracking
let tracking = Array.from({length: maxHeights.length}).fill(-1)
for(let i = 1; i < sortedDisks.length; i++) {
const currnetDisk = sortedDisks[i]
const [wc, pc, hc] = currnetDisk
for (let j = 0; j < i; j++) {
const otherDisk = sortedDisks[j]
const [wo, po, ho] = otherDisk
// check whether otherDisk can stack on topof current disk
if (wc > wo && pc > po && hc > ho) {
// if current max height is smaller than stacked height, do update
if (hc + maxHeights[j] > maxHeights[i]) {
maxHeights[i] = hc + maxHeights[j]
tracking[i] = j
if (maxHeight < maxHeights[i]) {
maxHeight = maxHeights[i]
maxHeightIndex = i
}
}
}
}
}
let res = []
let idx = maxHeightIndex
while (idx !== -1) {
res.unshift(sortedDisks[idx])
idx = tracking[idx]
}
return res
}
// Do not edit the line below.
exports.diskStacking = diskStacking;