leetcode 218. 天际线问题

题目:218. 天际线问题 - 力扣(LeetCode)

把一个矩形拆成左右两个点,左边向队列中增加一个高度,右边移除一个高度,求每个点上的最大高度,然后去重即可。

从数据规模看,O(n^2)的算法就够了,注意边界条件。

struct Node {
    int p;
    int h;
    bool isRight;
    Node(int p, int h, bool isRight) {
        this->p = p;
        this->h = h;
        this->isRight = isRight;
    }
};
bool myComp(Node* a, Node* b) {
    if (a->p < b->p) {
        return true;
    }
    if (a->p > b->p) {
        return false;
    }
    return a->h > b->h;
}
class Solution {
public:
    vector<Node*> arr;
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
        vector<vector<int>> ret;
        int n = buildings.size();
        for (int i = 0; i < n; i++) {
            Node* n1 = new Node(buildings[i][0], buildings[i][2], false);
            Node* n2 = new Node(buildings[i][1], buildings[i][2], true);
            arr.push_back(n1);
            arr.push_back(n2);
        }
        n *= 2;
        sort(arr.begin(), arr.end(), myComp);
        
        vector<int> h;
        int current = 0;
        int idx = 0;
        while (idx < n) {
            int l = idx;
            while (l < n && arr[l]->p == arr[idx]->p) {
                l++;
            }
            for (int j = idx; j < l; j++) {
                if (arr[j]->isRight) {
                    for (int k = 0; k < h.size(); k++) {
                        if (h[k] == arr[j]->h) {
                            h[k] = h[h.size() - 1];
                            h.pop_back();
                            break;
                        }
                    }
                    if (arr[j]->h == current) {
                        current = 0;
                        for (int k = 0; k < h.size(); k++) {
                            if (h[k] > current) {
                                current = h[k];
                            }
                        }
                    }
                } else {
                    h.push_back(arr[j]->h);
                    if (arr[j]->h > current) {
                        current = arr[j]->h;
                    }
                }
            }
            if (ret.empty() || ret[ret.size() - 1][1] != current) {
                vector<int> a;
                a.push_back(arr[idx]->p);
                a.push_back(current);
                ret.push_back(a);
            }
            idx = l;
        }
        return ret;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值