leetcode3288 最长上升路径的长度
给定长度为n的二维数组{x[i],y[i]}和一个整数k,其中0<=k<n,从中选中若干个点排序构成序列,求最长的点序列满足x[i]<x[i+1]并且y[i]<y[i+1],要求第k个点必须选择,返回最长序列的长度。
1<=n<=1E5; 0<=x[i],y[i]<=1E9;各个点互不相同
分析:可以拆分成如下几个子任务:
(1)求一维数组的lis的长度,使用二分插入将时间优化到O(nlogn);
(2)二维lis可以按x升序、y降序排序,转化为一维,求y的lis;
(3)必须选择第k个点,把小于k点的求一次,大于k点的求一次,然后拼起来就是答案;
class Solution {
public:
int maxPathLength(vector<vector<int>>& dot, int k) {
std::vector<std::vector<int>> A, B;
int n = dot.size();
for (int i = 0; i < n; i++) {
if (dot[i][0] < dot[k][0] && dot[i][1] < dot[k][1]) {
A.push_back({dot[i][0], dot[i][1]});
} else if (dot[i][0] > dot[k][0] && dot[i][1] > dot[k][1]) {
B.push_back({dot[i][0], dot[i][1]});
}
}
auto get = [](std::vector<std::vector<int>> &X) {
int n = X.size();
std::sort(X.begin(), X.end(), [](auto &x, auto &y) {
if (x[0] != y[0]) return x[0] < y[0];
return x[1] > y[1];
});
std::vector<int> f;
for (int i = 0; i < n; i++) {
auto it = std::lower_bound(f.begin(), f.end(), X[i][1]);
if (it == f.end()) {
f.push_back(X[i][1]);
} else {
*it = X[i][1];
}
}
return f.size();
};
return get(A) + 1 + get(B);
}
};