持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情
[面试题 08.13. 堆箱子](leetcode.cn/problems/ha…)
堆箱子。给你一堆n个箱子,箱子宽 wi、深 di、高 hi。箱子不能翻转,将箱子堆起来时,下面箱子的宽度、高度和深度必须大于上面的箱子。实现一种方法,搭出最高的一堆箱子。箱堆的高度为每个箱子高度的总和。
输入使用数组[wi, di, hi]表示每个箱子。
「示例1:」
输入:box = [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
输出:6
「示例2:」
输入:box = [[1, 1, 1], [2, 3, 4], [2, 6, 7], [3, 4, 5]]
输出:10
「提示:」
箱子的数目不大于3000个。
解题思路
先排序,排序规则是:
如果箱子的宽度不相同,按照宽度从小到大排序
如果箱子的宽度相同,深度不相同,按照深度从大到小排序
如果箱子的宽度和深度都相同,按照高度从大到小排序
排完序之后,箱子的宽度是递增的,宽度相同,深度是递减的,宽度和深度相同的时候,高度也是递减的,所以我们再比较的时候只用比较箱子的深度和高度即可
用一个dp数组保存该箱子能够搭建的最大高度,因为最少可以用该箱子搭建一个,所以初始化为该箱子的高度
遍历箱子,得到箱子 i 和箱子 j,如果箱子 j 的深度和高度都大于箱子 i,箱子 j 能搭建的最大高度,就等于箱子 i 能搭建的最大高度加上箱子 j 的高度和之前求的的可以搭建的最大高度比较,可以得到动态方程式
dp[j] = Math.max(dp[j], dp[i] + box[j][2])
在搭建的过程中去取得最大值
max = Math.max(max, dp[j])
代码实现
/**
* @param {number[][]} box
* @return {number}
*/
var pileBox = function(box) {
// 排序
box.sort((a, b) => a[0] === b[0] ? a[1] === b[1] ? b[2] - a[2] : b[1] - a[1] : a[0] - b[0])
const len = box.length
let dp = Array.from({length: len},(_, i) => box[i][2])
let max = 1
for (let i = 0; i < len; i++) {
max = Math.max(max, dp[i])
for (let j = i + 1; j < len; j++) {
if (box[j][1] > box[i][1] && box[j][2] > box[i][2]) {
dp[j] = Math.max(dp[j], dp[i] + box[j][2])
max = Math.max(max, dp[j])
}
}
}
return max
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;