Leetcode 218. 天际线问题-线段树

class Solution {
public:
struct TreeNode{
    // [st,ed)
    int st, ed, h;
    TreeNode * left, *right;   
    TreeNode(int s, int e, int hh):st(s), ed(e), h(hh), left(NULL), right(NULL){}
};

    // 维持了线段树 叶子节点进行分裂或者是重新计算,非叶子节点进行递归向下回调
    void insert(TreeNode* r, int st, int ed, int h)
    {
        if(r==NULL) return ;
        
        //两个部分是没有重叠的,直接返回就可以了
        if(r->st > ed || r->ed < st) return;
        
        if(r->left==NULL && r->right==NULL)
        {
            // 叶子节点进行分裂
            if(st<=r->st&&ed>=r->ed)// 包含在里面 不需要进行分裂
            {
                r->h = max(r->h, h);// 更新一下高度
                return ;
            }
            else
            {
                if(r->st < st) // 左边是需要分裂的
                {
                    r->left = new TreeNode(r->st, st-1, r->h);
                    r->right = new TreeNode(st, r->ed, r->h);
                    insert(r->right, st, ed, h);
                    check(r);
                }
                else 
                {
                    if(r->ed > ed)
                    {
                        r->left = new TreeNode(r->st, ed, r->h);
                        r->right = new TreeNode(ed+1, r->ed, r->h);
                        insert(r->left, st, ed, h); 
                        check(r);
                    }
                }
            }
        }
        else
        {
            // 非叶子节点直接进行递归的调用
            insert(r->left, st, ed, h);
            insert(r->right, st, ed, h);
            check(r);
        }
    }
    
    void check(TreeNode* r)// 左节点右节点都是叶子且他们的值相等就可以将这个节点给合并起来
    {
        if(r!=NULL && r->left!=NULL)
        {
            if(r->left->left==NULL && r->right->left==NULL && r->left->h == r->right->h)
            {
                r->h = r->left->h;
                free(r->left);
                free(r->right);
                r->left = NULL;
                r->right =NULL;
            }
        }
    }
    
    void buildans(TreeNode* r, vector<pair<int, int>>& ans, int &lasth)
    {
        if(r==NULL)return ;
        if(r->left==NULL && r->right==NULL)
        {
            if(r->h!=lasth)
            {
                lasth = r->h;
                ans.push_back(make_pair(r->st, r->h));
            }
            return;
        }
        else
        {
            buildans(r->left, ans, lasth);
            buildans(r->right, ans, lasth);
        }
    }
    
    vector<pair<int, int>> getSkyline(vector<vector<int>>& b) {
        TreeNode *root = new TreeNode(0, 0X7fffffff,0);
        for(int i=0 ;i<b.size();++i)
        {
            insert(root, b[i][0], b[i][1]-1, b[i][2]);
        }
        //遍历一下树就可以了 需要判断当前h是否等于上一个h,如果相等就不用输出了
        vector<pair<int, int>> ans;
        int lasth = 0;
        buildans(root, ans, lasth);
        
        return ans;
    }
};

猜你喜欢

转载自www.cnblogs.com/randyniu/p/9233040.html