当前位置: 面试刷题>> 俄罗斯套娃信封 (经典算法题500道)


### 题目描述补充 **俄罗斯套娃信封问题(Russian Doll Envelopes Problem)**: 给定一组信封,每个信封都有其宽度和高度的尺寸,问最多能使用多少个信封,使得在放置下一个信封时,这个信封的宽度和高度都必须严格小于前一个信封的宽度和高度。目的是要找出最长的信封序列(套娃序列),使得每个信封都能被下一个信封完全包裹。 ### 示例 假设有以下信封尺寸(以宽度和高度为一对表示): ``` [[5,4],[6,4],[6,7],[2,3]] ``` 最长套娃序列的长度是 3,即 `[2,3] -> [5,4] -> [6,7]`。 ### 解题思路 这个问题可以转化为最长递增子序列(LIS)问题,但需要考虑两个维度(宽度和高度)。由于LIS算法本身只考虑一维递增,我们需要通过某种方式将二维问题转化为一维。常见的方法是先将信封按照宽度进行排序(如果宽度相同,则按高度降序排序),然后只对高度这一维使用LIS算法。 ### PHP 示例代码 ```php function maxEnvelopes($envelopes) { // 按宽度升序排序,宽度相同则按高度降序排序 usort($envelopes, function($a, $b) { if ($a[0] == $b[0]) { return $b[1] - $a[1]; } return $a[0] - $b[0]; }); $heights = array_column($envelopes, 1); return lengthOfLIS($heights); } function lengthOfLIS($nums) { $n = count($nums); if ($n <= 1) return $n; $dp = array_fill(0, $n, 1); $maxLength = 1; for ($i = 1; $i < $n; $i++) { for ($j = 0; $j < $i; $j++) { if ($nums[$i] > $nums[$j]) { $dp[$i] = max($dp[$i], $dp[$j] + 1); } } $maxLength = max($maxLength, $dp[$i]); } return $maxLength; } // 示例 $envelopes = [[5,4],[6,4],[6,7],[2,3]]; echo maxEnvelopes($envelopes); // 输出 3 ``` ### Python 示例代码 ```python def maxEnvelopes(envelopes): # 按宽度升序排序,宽度相同则按高度降序排序 envelopes.sort(key=lambda x: (x[0], -x[1])) heights = [env[1] for env in envelopes] return lengthOfLIS(heights) def lengthOfLIS(nums): dp = [1] * len(nums) maxLength = 1 for i in range(1, len(nums)): for j in range(i): if nums[i] > nums[j]: dp[i] = max(dp[i], dp[j] + 1) maxLength = max(maxLength, dp[i]) return maxLength # 示例 envelopes = [[5,4],[6,4],[6,7],[2,3]] print(maxEnvelopes(envelopes)) # 输出 3 ``` ### JavaScript 示例代码 ```javascript function maxEnvelopes(envelopes) { // 按宽度升序排序,宽度相同则按高度降序排序 envelopes.sort((a, b) => { if (a[0] === b[0]) return b[1] - a[1]; return a[0] - b[0]; }); const heights = envelopes.map(env => env[1]); return lengthOfLIS(heights); } function lengthOfLIS(nums) { const dp = new Array(nums.length).fill(1); let maxLength = 1; for (let i = 1; i < nums.length; i++) { for (let j = 0; j < i; j++) { if (nums[i] > nums[j]) { dp[i] = Math.max(dp[i], dp[j] + 1); } } maxLength = Math.max(maxLength, dp[i]); } return maxLength; } // 示例 const envelopes = [[5,4],[6,4],[6,7],[2,3]]; console.log(maxEnvelopes(envelopes)); // 输出 3 // 码小课网站中有更多相关内容分享给大家学习 ``` 以上代码示例均实现了俄罗斯套娃信封问题的解决方案,并展示了如何在PHP、Python和JavaScript中编写。
推荐面试题