算法——俄罗斯套娃信封问题

134 阅读1分钟

题目(俄罗斯套娃信封)

给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。

当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。

请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

注意:不允许旋转信封。

链接:leetcode.cn/problems/ru…

举例

输入:envelopes = [[5,4],[6,4],[6,7],[2,3]]
输出:3
解释:最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。

输入: envelopes = [[1,1],[1,1],[1,1]]
输出: 1

解题思路

1. 先对二维数组排序,宽度以升序排列;宽度一致的,高度以降序排列。
2. 定义一个变量result,用来记录每次高度的比较结果。

代码实现

/**
 * 函数描述: 俄罗斯套娃信封
 * @param {Array} arr 信封
 * @return {Number} result Max套娃信封
 */
const envelopesOfGroup = (arr) => {
    let result = 1;
    if (arr.length === result) return result;
    const newArr = [], len = arr.length;
    for (let i = 0; i < len; i++) newArr.push(1);
    // 宽度以升序排列;宽度一致的,高度以降序排列
    arr.sort((a, b) => a[0] === b[0] ? b[1] - a[1] : a[0] - b[0]);
    for (let i = 0; i < len; i++) {
        let a = arr[i];
        for (let j = 0; j < i; j++) {
            let b = arr[j];
            if (a[1] > b[1]) newArr[i] = Math.max(newArr[j] + 1, newArr[i]);
        }
        result = Math.max(result, newArr[i]);
    }
    return result;
}
console.log(envelopesOfGroup([[5, 4], [6, 4], [6, 7], [2, 3]])); // 3
console.log(envelopesOfGroup([[1, 1], [1, 1], [1, 1]])); // 1
console.log(envelopesOfGroup([[1, 1]])); // 1
console.log(envelopesOfGroup([[5, 4], [6, 4], [6, 7], [2, 3], [3, 4], [5, 6], [6, 10], [7, 2]])); // 4
console.log(envelopesOfGroup([[1, 2], [3, 6], [4, 6], [4, 9], [4, 3], [4, 7], [5, 5], [8, 12]])); // 4
console.log(envelopesOfGroup([[1, 2], [3, 6], [4, 6], [4, 9], [4, 3], [4, 7], [5, 8], [8, 12]])); // 5