[Algorithm] Disk height (DP + back tracking)

发布时间 2023-03-26 20:13:51作者: Zhentiw

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;