【LeetCode】每日一题 面试题 08.13. 堆箱子

72 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;