LeetCode 每日 1 题:堆叠长方体的最大高度

123 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第 11 天,点击查看活动详情

堆叠长方体的最大高度

原题地址

给你 n 个长方体 cuboids ,其中第 i 个长方体的长宽高表示为 cuboids[i]=[widthi,lengthi,heighti]cuboids[i] = [width_i, length_i, height_i](下标从 0 开始)。请你从 cuboids 选出一个 子集 ,并将它们堆叠起来。

如果 widthi<=widthjwidth_i <= width_jlengthi<=lengthjlength_i <= length_jheighti<=heightjheight_i <= height_j ,你就可以将长方体 i 堆叠在长方体 j 上。你可以通过旋转把长方体的长宽高重新排列,以将它放在另一个长方体上。

返回 堆叠长方体 cuboids 可以得到的 最大高度

示例 1:

输入:cuboids = [[50,45,20],[95,37,53],[45,23,12]]
输出:190
解释:
第 1 个长方体放在底部,53x37 的一面朝下,高度为 95 。
第 0 个长方体放在中间,45x20 的一面朝下,高度为 50 。
第 2 个长方体放在上面,23x12 的一面朝下,高度为 45 。
总高度是 95 + 50 + 45 = 190

示例 2:

输入:cuboids = [[38,25,45],[76,35,3]]
输出:76
解释:
无法将任何长方体放在另一个上面。
选择第 1 个长方体然后旋转它,使 35x3 的一面朝下,其高度为 76

示例 3:

输入:cuboids = [[7,11,17],[7,17,11],[11,7,17],[11,17,7],[17,7,11],[17,11,7]]
输出:102
解释:
重新排列长方体后,可以看到所有长方体的尺寸都相同。
你可以把 11x7 的一面朝下,这样它们的高度就是 17 。
堆叠长方体的最大高度为 6 * 17 = 102

提示:

  • n == cuboids.length
  • 1 <= n <= 100
  • 1<=widthi,lengthi,heighti<=1001 <= width_i, length_i, height_i <= 100

思路分析

  1. 根据题目描述,每个箱子都可以旋转,那么我们可以将每个箱子旋转后做为一个新箱子放入数组 cuboids 中;
  2. 首先考虑箱子的长宽高的都不同的情况,这种情况下旋转后肯定不可能放到自己身上,即不可能拿到重复的箱子;其次,如果箱子的其中两边相同,那么旋转后依旧不能放到自己身上;最后,如果箱子的三遍都相同,那么就没必要旋转,因为旋转后跟自己是一样的,这样处理的话就会有重复的箱子;
  3. 因此按照步骤2的逻辑将旋转后的箱子追加到数组 cuboids 中,得到我们要处理的所有的箱子;
  4. 扩展完毕后,题目所需要的也就是从扩展后的数组中找出组合成的最高高度;
  5. 先给箱子进行排序,长度最小的在前面,长度相等宽度最小的在前面,长宽都相等高度最小的在前面,按照这个规则排序,然后遍历处理;
  6. 定义动态规划数组 dpdp[i] 表示以 cuboids[i] 箱子作为最底层的最大高度,定义 res 为最后返回的结果,那么在二次遍历循环中,dp[i] = Math.max(dp[i], dp[j] + cuboids[i][2]),而 resdp[i] 的最大值即可。

AC 代码

/**
 * @param {number[][]} cuboids
 * @return {number}
 */
var maxHeight = function(cuboids) {
    let len = cuboids.length
  // 把盒子能旋转出来的样式都拓展出来
  for (let i = 0; i < len; i++) {
    let [width, length, height] = cuboids[i]
    // 长宽高相等 不用扩展
    if(width === length && length === height) continue
    else if(width === length){
      cuboids.push([width, height, length])
      cuboids.push([height, width, length])
    }
    else if(length === height){
      cuboids.push([length, width, height])
      cuboids.push([length, height, width])
    }
    else if(width === height){
      cuboids.push([length, width, height])
      cuboids.push([width, height, length])
    }
    else {
      cuboids.push([width, height, length])
      cuboids.push([length, width, height])
      cuboids.push([length, height, width])
      cuboids.push([height, width, length])
      cuboids.push([height, length, width])
    }
  }
  cuboids.sort((a,b) => {
    if(a[0] === b[0]){
      if(a[1] === b[1]) return a[2] - b[2]
      return a[1] - b[1]
    }
    return a[0] - b[0]
  })
  let dp = cuboids.map(x => x[2])
  let res = 0
  for (let i = 0; i < dp.length; i++) {
    for (let j = 0; j < i; j++) {
      if(cuboids[i][0] >= cuboids[j][0] && 
         cuboids[i][1] >= cuboids[j][1] && 
         cuboids[i][2] >= cuboids[j][2]) 
         dp[i] = Math.max(dp[i], dp[j] + cuboids[i][2])
    }
    res = Math.max(res, dp[i])
  }
  return res
};

结果:

  • 执行结果: 通过
  • 执行用时:128 ms, 在所有 JavaScript 提交中击败了0.00%的用户
  • 内存消耗:46.9 MB, 在所有 JavaScript 提交中击败了0.00%的用户
  • 通过测试用例:83 / 83

END