开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第 11 天,点击查看活动详情。
堆叠长方体的最大高度
原题地址
给你 n 个长方体 cuboids ,其中第 i 个长方体的长宽高表示为 (下标从 0 开始)。请你从 cuboids 选出一个 子集 ,并将它们堆叠起来。
如果 且 且 ,你就可以将长方体 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.length1 <= n <= 100
思路分析
- 根据题目描述,每个箱子都可以旋转,那么我们可以将每个箱子旋转后做为一个新箱子放入数组
cuboids中; - 首先考虑箱子的长宽高的都不同的情况,这种情况下旋转后肯定不可能放到自己身上,即不可能拿到重复的箱子;其次,如果箱子的其中两边相同,那么旋转后依旧不能放到自己身上;最后,如果箱子的三遍都相同,那么就没必要旋转,因为旋转后跟自己是一样的,这样处理的话就会有重复的箱子;
- 因此按照步骤2的逻辑将旋转后的箱子追加到数组
cuboids中,得到我们要处理的所有的箱子; - 扩展完毕后,题目所需要的也就是从扩展后的数组中找出组合成的最高高度;
- 先给箱子进行排序,长度最小的在前面,长度相等宽度最小的在前面,长宽都相等高度最小的在前面,按照这个规则排序,然后遍历处理;
- 定义动态规划数组
dp,dp[i]表示以cuboids[i]箱子作为最底层的最大高度,定义 res 为最后返回的结果,那么在二次遍历循环中,dp[i] = Math.max(dp[i], dp[j] + cuboids[i][2]),而res取dp[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