chenfy27的刷题记录

导航

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);
    }
};

posted on 2024-12-06 21:40  chenfy27  阅读(2)  评论(0编辑  收藏  举报