Problem: 354. 俄罗斯套娃信封问题
文章目录
- 思路
- 解题方法
- 复杂度
- Code
思路
这个问题可以转换为最长递增子序列(Longest Increasing Subsequence,LIS)问题。先对信封按宽度升序排序,当宽度相同时,按高度降序排序。然后在排序后的信封数组中找到最长的严格递增的高度序列。
解题方法
首先对信封进行排序,接着使用动态规划的思想求解最长递增子序列。具体实现时,使用一个ends数组存储递增子序列的结尾元素,通过二分查找确定当前元素应该放置的位置。
复杂度
时间复杂度:
O ( n l o g n ) O(nlogn) O(nlogn),其中nn是信封的数量。主要开销来自于排序和二分查找。
空间复杂度:
O ( n ) O(n) O(n),用于存储排序后的信封数组和ends数组。
Code
class Solution {public int maxEnvelopes(int[][] envelopes) {int n = envelopes.length;// 按照信封的宽度排序 如果宽度相同 按照高度从大到小排序Arrays.sort(envelopes, (a, b) -> a[0] != b[0] ? (a[0] - b[0]) : (b[1] - a[1]));// 根据高度LIS模板int[] ends = new int[n];int len = 0;for (int i = 0, find; i < n; i++) {find = bs(ends, len, envelopes[i][1]);if (find == -1) {ends[len++] = envelopes[i][1];} else {ends[find] = envelopes[i][1];}}return len;}public int bs(int[] ends, int len, int num) {int l = 0, r = len - 1, m, ans = -1;while(l <= r) {m = (l + r) / 2;if(ends[m] >= num) {ans = m;r = m - 1;} else {l = m + 1;}}return ans;}
}