携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 25 天,点击查看活动详情
马戏团人塔
原题地址
有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一点。已知马戏团每个人的身高和体重,请编写代码计算叠罗汉最多能叠几个人。
示例:
输入:height = [65,70,56,75,60,68] weight = [100,150,90,190,95,110]
输出:6
解释:从上往下数,叠罗汉最多能叠 6 层:(56,90), (60,95), (65,100), (68,110), (70,150), (75,190)
提示:
height.length == weight.length <= 10000
思路分析
方法一
- 首先组装数据,将每个人的身高体重组成一个对象,将每个人的信息存储到一个数组
data中; - 将数组按照身高升序,若身高相同则体重降序的方式进行排序;
- 因为身高已经升序了,因此循环判断其体重即可,若
data[i].weight > data[j].weight,则res的 第i项 为res[i]与res[j] + 1的最大值; - 寻找出
res中的最大值返回即可。
方法二
- 步骤1,2同方法一,得到排序后的数据;
- 使用动态规划来维护一个动态数组
res,利用二分查找找出元素所在位置,若为data.length则给res添加元素,若在1到data.length - 1的区间内就替换元素,这样可以得到满足条件的res数组; - 因为题目要求返回数量即可,因此返回
res.length就可以了。
方法二
AC 代码
方法一
/**
* @param {number[]} height
* @param {number[]} weight
* @return {number}
*/
var bestSeqAtIndex = function(height, weight) {
const data = []
const res = [1]
height.forEach((height, index) => {
data.push({ height: height, weight: weight[index] })
})
data.sort((a, b) => a.height - b.height || b.weight - a.weight)
for (let i = 1; i < data.length; i++){
res[i] = 1
for (let j = 0; j < i; j++) {
if(data[i].weight > data[j].weight) {
res[i] = Math.max(res[i], res[j] + 1)
}
}
}
return Math.max(...res)
};
结果:
- 执行结果: 通过
- 执行用时:6008 ms, 在所有 JavaScript 提交中击败了9.80%的用户
- 内存消耗:49.6 MB, 在所有 JavaScript 提交中击败了70.59%的用户
- 通过测试用例:43 / 43
方法二
/**
* @param {number[]} height
* @param {number[]} weight
* @return {number}
*/
var bestSeqAtIndex = function(height, weight) {
const data = []
weight.forEach((w, i) => {
data.push({ height: height[i], weight: w })
})
data.sort((a, b) => a.height - b.height || b.weight - a.weight)
let res = [data[0]]
data.forEach(item => {
let left = 0, right = res.length - 1
while(right >= left) {
let mid = Math.floor((right - left) / 2 + left)
res[mid].weight >= item.weight ? right = mid - 1 : left = mid + 1
}
res[left] = item
})
return res.length
};
结果:
- 执行结果: 通过
- 执行用时:144 ms, 在所有 JavaScript 提交中击败了84.31%的用户
- 内存消耗:49.6 MB, 在所有 JavaScript 提交中击败了78.43%的用户
- 通过测试用例:43 / 43